第一步:创建一个基于对话框的MFC工程
第二部:创建一个新的类RECVPARAM用于接受主线程的句柄和套接字
第三步:新建一个新的按钮用来启动多线程,设置名字和ID
第四步:双击编写该按钮的函数
1.套接字版本初始化
WORD WvesionRequested; // 保存WinSock库的版本号
WSADATA wsadata;
int err;
WvesionRequested = MAKEWORD(1,1); // 请求版本号的WORD值
err = WSAStartup(WvesionRequested, &wsadata);
if(err != 0)
{
return 0;
}
if (LOBYTE(wsadata.wVersion)!=1 || HIBYTE(wsadata.wVersion!=1))
{
WSACleanup();
return 0;
}
2.初始化套接字
SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0);
3.绑定
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof SOCKADDR);
4.创建接受数据多线程
HANDLE hThread = CreateThread(NULL,0,RecvProc,(LPVOID)pRecvParam,0,NULL);
5.关闭套接字
closesocket(m_socket);
上面个这些是实现函数,需要修改才能使用。
第五步:编写线程处理函数(在CADODlg类里面声明该函数为静态函数)
DWORD CADODlg::RecvProc(LPVOID lpParameter)
{
// 获取主线程传递的套接字的窗口句柄
SOCKET sock = ((RECVPARAM*)lpParameter)->sock;
HWND hwnd = ((RECVPARAM*)lpParameter)->hwnd;
AfxMessageBox(TEXT("Thread"));
delete lpParameter;
SOCKADDR_IN addrFrom;
int len = sizeof (SOCKADDR);
char recvBuf[200];
char tempBuf[300];
int retval;
while(1)
{
//接受数据
// AfxMessageBox(TEXT("begin1"));
retval = recvfrom(sock,recvBuf,200,0,(SOCKADDR*)&addrFrom,&len);
AfxMessageBox(TEXT("recv isnot wait"));
if(SOCKET_ERROR==retval)
{
//AfxMessageBox(TEXT("begin2"));
break;
}
sprintf(tempBuf, "%s say: %s",inet_ntoa(addrFrom.sin_addr),recvBuf);
::PostMessage(hwnd,WM_RECVDATA, 0, (LPARAM)tempBuf); // 显示每条数据
}
return 0;
}
第六步:绑定WM_RECVDATA宏的函数
1.在resource.h 头文件定义宏
2.在CADODlg类头文件中 添加函数说明
3.在CADODlg类cpp文件中添加消息映射
3.实现该函数
void CADODlg::OnRecvData(WPARAM wParam, LPARAM lParam)
{
CString str = (char*)lParam;
CString strTemp;
GetDlgItemText(IDC_EDIT_RECV,strTemp); // IDC_EDIT_RECV 编辑框ID
str+="\r\n";
str+=strTemp;
SetDlgItemText(IDC_EDIT_RECV,str);
}