您的位置:首页 > 其它

WSAAsyncSelect之MFC模型

2017-05-25 17:17 232 查看
WSAAsyncSelect模型允许应用程序以Windows消息的方式接收网络事件通知。许多对性能要求不高的网络应用程序都采用WSAAsyncSelect模型,MFC的CSocket类也使用了它。

        WSAAsyncSelect自动把套接字设为非阻塞模式,并且为套接字绑定一个窗口句柄,当有网络事件发生时,便向这个窗口发送消息。

        intWSAAsyncSelect(

        SOCKET s,                  //需要设置的套接字句柄

        HWND  hWnd,     //指定一个窗口句柄, 套接字的通知消息将被发到此窗口中

       u_int    wMsg,     //网络事件到来的ID,可以在WM_USER以上数值中任意指定一个值

       long    IEvent     //指定哪些通知码需要发送

                                 //FD_READ可以读套接字

                                 //FD_WRITE 可以写套接字

                                //FD_ACCEPT 监听套接字有连接接入

                               //FD_CONNET  如果套接字连接对方主机,连接完成后会收到这个通知码

                              //FD_CLOSE 检测到套接字对应的连接被关闭

)

       回传过来的消息类型与注册的wMsg相同,wParam等于套接字句柄,lParam通过WSAGETSELECTEVENT转义后就是FD_READ,FD_WRITE,FD_ACCEPT,FD_CONNET,FD_CLOSE

        代码如下:

        新建一个基于MFC对话框的工程,工程名为test,然后在testDlg.h中定义      

[cpp] view
plain copy

#include "winsock2.h"  

#pragma comment(lib, "WS2_32")  

#define WM_SOCKET (WM_USER+1)   

同时在该文件中加入一个自定义消息处理函数

[cpp] view
plain copy

afx_msg LRESULT OnSocketMsg(WPARAM wParam,LPARAM lParam);  

在testDlg.cpp中定义

[cpp] view
plain copy

ON_MESSAGE(WM_SOCKET,OnSocketMsg)  

在OnInitDialog中加入自己的初始化代码

[cpp] view
plain copy

// TODO: 在此添加额外的初始化代码  

  

    WSADATA wsaData;  

    WORD sockVersion = MAKEWORD(2, 2);  

    if(WSAStartup(sockVersion, &wsaData) != 0)  

    {  

        return 0;  

    }  

    USHORT nPort=4567;  

    SOCKET s=socket(AF_INET,SOCK_STREAM,0);  

    sockaddr_in sin;  

    sin.sin_family=AF_INET;  

    sin.sin_port=ntohs(nPort);  

    sin.sin_addr.S_un.S_addr=INADDR_ANY;  

    if(bind(s,(sockaddr*)&sin,sizeof(sin))==SOCKET_ERROR)  

    {  

        DWORD error=GetLastError();  

        return TRUE;  

    }  

  

    WSAAsyncSelect(s,m_hWnd,WM_SOCKET,FD_ACCEPT|FD_CLOSE);  

    listen(s,5);  

添加自定义消息函数的处理:

[cpp] view
plain copy

LRESULT CtestDlg::OnSocketMsg(WPARAM wParam,LPARAM lParam)  

{  

    SOCKET s=wParam;  

    CString strContent;  

    if(WSAGETSELECTERROR(lParam))  

    {  

        closesocket(s);  

        return false;  

    }  

    switch(WSAGETSELECTEVENT(lParam))  

    {  

    case FD_ACCEPT://检测到有套接字连上来  

        {  

            SOCKET client=accept(s,NULL,NULL);  

            WSAAsyncSelect(client,m_hWnd,WM_SOCKET,FD_READ|FD_WRITE|FD_CLOSE);  

            CString strContent;  

            GetDlgItemText(IDC_EDIT1,strContent);  

            if(!strContent.IsEmpty())  

            {  

                strContent+="\r\n";  

            }             

            strContent+="有客户端连上来了";  

            SetDlgItemText(IDC_EDIT1,strContent);//将内容显示到Edit控件  

        }  

        break;  

    case FD_WRITE:  

        {  

        }  

        break;  

    case FD_READ:  

        {  

            char szText[1024]={0};  

            if(recv(s,szText,1024,0)==-1)  

                closesocket(s);  

            else  

            {                 

                GetDlgItemText(IDC_EDIT1,strContent);  

                if(!strContent.IsEmpty())  

                {  

                    strContent+="\r\n";  

                }  

                CString strTemp;  

                strTemp.Format("%s",szText);  

                strContent+=strTemp;  

                SetDlgItemText(IDC_EDIT1,strContent);//将内容显示到Edit控件中  

            }  

        }  

        break;  

    case FD_CLOSE:  

        {  

            closesocket(s);  

            GetDlgItemText(IDC_EDIT1,strContent);  

            if(!strContent.IsEmpty())  

            {  

                strContent+="\r\n";  

            }             

            strContent+="有客户端断开了";  

            SetDlgItemText(IDC_EDIT1,strContent);//将内容显示到Edit控件中  

        }  

        break;  

    }  

    return true;  

}  

对WM_DESTROY消息处理,清理套接字库

[cpp] view
plain copy

void CtestDlg::OnDestroy()  

{  

    CDialog::OnDestroy();  

    WSACleanup();  

    // TODO: 在此处添加消息处理程序代码  

}  

原文转载自: 


http://blog.csdn.net/cloud95/article/details/7688786

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: