MFC下多线程实现socket通信

1.自定义消息4个步骤:
1>.在头文件中定义消息值  
     #define WM_RECVDATA WM_USER+1

2>.在类的头文件中声明消息响应函数
afx_msg void OnRecvData(WPARAM wParam, LPARAM lParam);

3>.在源文件中的 BEGIN_MESSAGE_MAP 即END_MESSAGE_MAP之间添加自定义消息映射
ON_MESSAGE(WM_RECVDATA,OnRecvData)

4>.实现消息响应函数 OnRecvData();

2.定义消息传递数据结构体

//传递结构体参数
struct RECVPARAM{
     SOCKET sock;   //传递套接字对象
     HWND hwnd;    //传递主窗口句柄
};

3.定义全局的消息处理函数
DWORD WINAPI RecvThreadProc(LPVOID lParameter)
{
     SOCKET sock = ((RECVPARAM*)lParameter)->sock;
     HWND hwnd = ((RECVPARAM*)lParameter)->hwnd;
    
     char recvBuf[500] = {0};
     memset(recvBuf,0,500);
     while(true)
     {
          //消息循环
          memset(recvBuf,0,500);  //必须要每次清空
          recv(sock,recvBuf,50,0);
          // 从服务器接受的数据不为空
          if (strcmp(recvBuf,"") != 0)
          {
               ::SendMessage(hwnd,WM_RECVDATA,0,(LPARAM)recvBuf);
          }

     }

     return 0;
}
4. 开辟一个线程,等待接受服务器的数据
     在OnInitDialog()函数中添加:
     RECVPARAM *pRecvParam = new RECVPARAM;
     pRecvParam->hwnd = m_hWnd;
     pRecvParam->sock = m_socketClient;
     HANDLE handle = CreateThread(NULL,0,RecvThreadProc,(LPVOID)pRecvParam,0,NULL);
     CloseHandle(handle);

5.初始化socket环境,创建socket,以及连接到目标IP地址
void CSendmessageDlg::InitSocketClient()
{
     WORD wVersionRequest; //版本号
     WSADATA wsaData;
     int err;
     wVersionRequest = MAKEWORD(1,1);
     err = WSAStartup(wVersionRequest,&wsaData);
     if (err != 0)
     {    
          WSACleanup();
          MessageBox(_T("WSA startup 失败! "));
          return ;
     }
    
     if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
     {
          WSACleanup();
          MessageBox(_T("版本不符!"));
          return;
     }
    

     //只需客户端socket,连接到指定的IP和端口号
     SOCKADDR_IN addrSrv;
     addrSrv.sin_addr.S_un.S_addr = inet_addr("192.168.0.201");
     addrSrv.sin_family = AF_INET;
     addrSrv.sin_port = htons(5000);
     m_socketClient =  socket(AF_INET,SOCK_STREAM,0);
     int conn =  connect(m_socketClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
     if (conn != 0) 
     {
         //  0表示连接成功 否则不成功
          MessageBox(_T("connected Failed!"));
          return;
     }
}

6.向服务器(目标主机)发送数据,等待接受其回复的数据:
     CString strSend;
     GetDlgItemText(IDC_EDIT_CLIENT,strSend);    
     send(m_socketClient,strSend,sizeof(strSend)+1,0);

7.所有从服务器接受的数据,均通过消息响应函数OnRecvData()来处理

void CSendmessageDlg::OnRecvData(WPARAM wParam,LPARAM lParam)
{     
     //数据通过lParam参数来传递
     CString strTemp = (char*)lParam;
     // m_strRecv 是为了数据能连续显示 
     m_strRecv += "\r\n";
     m_strRecv += strTemp;
     //将数据显示在编辑框中
     SetDlgItemText(IDC_EDIT_SERVER,m_strRecv);    
}

至此,本主机向目标主机发送数据,就能实时接收并显示目标主机回复的数据了。自己草草记录一下,也希望对你有所帮助。







©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页