异步套接字通讯[转]

 
古城
@ 2007.08.28
分类:技术笔记
点击:2731  评论:0
 
 
 
必须使用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;
    }
    
}
 
 
 
 
 

本文评论

 
 

发表评论

你的评论
← 填你的昵称
以下内容非必填,可根据需要填写
← 可以展示在你的评论上方
← 不会在页面展示
← 不会在页面展示
← 只给我看?勾选上
这是一个别人称之为角落的世界
幸而,它的确是我的世界