异步套接字通讯[转]
古城
必须使用2.0版本以上的套接字库,所以不能使用AfxSocketInit(),因为它初始化的是1.1版本的套接字库
在InitInstance()函数中使用WSAStartup()函数初始化:
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return FALSE;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
WSACleanup( );
return FALSE;
}
还需要在析构函数中调用WSACleanup()函数中止对套接字库的使用。
还需要加载ws2_32.lib对动态链接库的引用
还需要#i nclude “winsock2.h”
在程序开始之前需要初始化异步接收的套接字:
BOOL CChatDlg::InitSocket()
{
m_socket=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,0);
//创建异步套接字
if(INVALID_SOCKET==m_socket)
{
MessageBox("创建套接字失败!");
return FALSE;
}
SOCKADDR_IN addrSock;
addrSock.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSock.sin_family=AF_INET;
addrSock.sin_port=htons(6000);
if(SOCKET_ERROR==bind(m_socket,(SOCKADDR*)&addrSock,sizeof(SOCKADDR)))
{
MessageBox("绑定失败!");
return FALSE;
}
if(SOCKET_ERROR==WSAAsyncSelect(m_socket,m_hWnd,UM_SOCK,FD_READ))
//m_hWnd接收网络事件消息的窗口的句柄
{
MessageBox("注册网络读取事件失败!");
return FALSE;
}
return TRUE;
}
在.h中定义用户消息:
#define UM_SOCK WM_USER+1
//当系统从端口接收到数据,就会向指定窗体发送该消息
在.h中定义消息响应函数:
afx_msg void OnSock(WPARAM,LPARAM);
在.cpp中定义消息与函数的对应关系:
ON_MESSAGE(UM_SOCK,OnSock)
OnSock()函数:
void CChatDlg::OnSock(WPARAM wParam,LPARAM lParam)
//wParam指定所使用的套接字,lParam低字节指定消息种类,高字节指定错误代码
{
switch(LOWORD(lParam))
{
case FD_READ:
WSABUF wsabuf;
wsabuf.buf=new char[200];
wsabuf.len=200;
DWORD dwRead;
DWORD dwFlag=0;
SOCKADDR_IN addrFrom;
int len=sizeof(SOCKADDR);
CString str;
CString strTemp;
HOSTENT *pHost;
if(SOCKET_ERROR==WSARecvFrom(m_socket,&wsabuf,1,&dwRead,&dwFlag,
(SOCKADDR*)&addrFrom,&len,NULL,NULL))
{
MessageBox("数据接收失败!");
return;
}
pHost=gethostbyaddr((char*)&addrFrom.sin_addr.S_un.S_addr,4,AF_INET);
//str.Format("%s说
:%s",inet_ntoa(addrFrom.sin_addr),wsabuf.buf);
str.Format("%s说 :%s",pHost->h_name,wsabuf.buf);
str+="\r\n";
GetDlgItemText(IDC_EDIT_RECV,strTemp);
str+=strTemp;
SetDlgItemText(IDC_EDIT_RECV,str);
break;
}
}
发送数据的函数:
void CChatDlg::OnBtnSend()
{
// TODO: Add your control notification handler code
here
DWORD dwIP;
CString strSend;
WSABUF wsabuf;
DWORD dwSend;
int len;
CString strHostName;
SOCKADDR_IN addrTo;
HOSTENT* pHost;
if(GetDlgItemText(IDC_EDIT_HOSTNAME,strHostName),strHostName=="")
{
((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1))->GetAddress(dwIP);
addrTo.sin_addr.S_un.S_addr=htonl(dwIP);
}
else
{
pHost=gethostbyname(strHostName);
addrTo.sin_addr.S_un.S_addr=*((DWORD*)pHost->h_addr_list[0]);
}
addrTo.sin_family=AF_INET;
addrTo.sin_port=htons(6000);
GetDlgItemText(IDC_EDIT_SEND,strSend);
len=strSend.GetLength();
wsabuf.buf=strSend.GetBuffer(len);
wsabuf.len=len+1;
SetDlgItemText(IDC_EDIT_SEND,"");
if(SOCKET_ERROR==WSASendTo(m_socket,&wsabuf,1,&dwSend,0,
(SOCKADDR*)&addrTo,sizeof(SOCKADDR),NULL,NULL))
{
MessageBox("发送数据错误!");
return;
}
}
本文评论
发表评论
这是一个别人称之为角落的世界
幸而,它的确是我的世界