您的位置:首页 > 其它

Unicode下,socket的Sendto/RecvFrom函数的使用二

2016-06-27 15:51 232 查看
/***********************************************************************************************************************************学习课程:孙鑫老师的VC++教程的第十五课《多线程编程》遭遇问题:课程的源代码是在VC6.0中编写的,在VC++2010的Unicode(默认)编码的开发环境中不能通过,有的地方需要作出相应的改变。 ****************************************************************************************************************************************/ 改动1:课程中用到一个自写的消息映射,在头文件的声明与在源文件中添加的消息映射分别如下:1.声明:afx_msg void OnRecvData(WPARAM wParam,LPARAM lParam);2.消息映射:ON_MESSAGE(WM_RECVDATA,OnRecvData)在VC++2010中,消息的检查更为严格,这样的消息映射在检查时不允许通过。在VC++2010中,OnMessage返回值必须为LRESULT,其形式为:afx_msg LRESULT OnMessage(WPARAM, LPARAM);相应的消息映射应改为: ON_MESSAGE(WM_RECVDATA,&CChatRoomDlg::OnRecvData)改动2:在发送按钮的消息相应函数中,有如下代码: sendto(m_socket,strSend,strSend.GetLength()+1,0, (SOCKADDR*)&addrTo,sizeof(SOCKADDR));sreSend为CString对象,而sendto的第二个参数所要类型为char*,CString在多字节编码的开发环境中可以默认转换为char*类型,但在Unicode环境中便会报错。所以需要进行强制转换,改动后的代码如下: sendto(m_socket,(char*)strSend.GetBuffer(),strSend.GetLength()*2+2,0, //UNICODE下不支持(char*)strSend这样的强制转换//发送的长度也应为原来的两倍 (SOCKADDR*)&addrTo,sizeof(SOCKADDR)); strSend.ReleaseBuffer(); //当调用GetBuffer后在合适的地方ReleaseBuffer是个好习惯改动3:在线程函数RecvProc中,最后把相关数据用SetDlgItemText函数显示在编辑框中时,由于SetDlgItemText需要的是宽字符类型,接收到的IP信息与消息内容必须都转换为宽字符类型,详细请参考改动后的注释。课程原来的代码如下:DWORD WINAPI CChatDlg::RecvProc(LPVOID lpParameter){ SOCKET sock=((RECVPARAM*)lpParameter)->sock; HWND hwnd=((RECVPARAM*)lpParameter)->hwnd; delete lpParameter; SOCKADDR_IN addrFrom; int len=sizeof(SOCKADDR); char recvBuf[200]; char tempBuf[300]; int retval; while(TRUE) { retval=recvfrom(sock,recvBuf,200,0,(SOCKADDR*)&addrFrom,&len); if(SOCKET_ERROR==retval) break; sprintf(tempBuf,"%s说: %s",inet_ntoa(addrFrom.sin_addr),recvBuf); ::PostMessage(hwnd,WM_RECVDATA,0,(LPARAM)tempBuf); } return 0;}改动后的代码如下:DWORD WINAPI CChatRoomDlg::RecvProc(LPVOID lpParameter){ SOCKET sock=((RECVPARAM*)lpParameter)->sock; HWND hwnd=((RECVPARAM*)lpParameter)->hwnd; delete lpParameter; SOCKADDR_IN addrFrom; int len=sizeof(SOCKADDR); wchar_t recvBuf[200]; wchar_t tempBuf[200]; //wchar_t ipstr[100]; //DWORD i=100; int retval; while(TRUE) { retval=recvfrom(sock,(char*)recvBuf,200,0,(SOCKADDR*)&addrFrom,&len); if(SOCKET_ERROR==retval) break;//也可以用这个函数来获取发送端的地址信息,//地址信息将保存在ipstr中,不仅包括ip地址,还有端口 //ipstr的类型为宽字符类型,在格式化输出的时候不需要做类型转换 //WSAAddressToString((SOCKADDR*)&addrFrom,len,NULL,ipstr,&i); //因为inet_ntoa函数返回的ip地址是char*类型,//需要转换成wchar_T*类型以便格式 //化输出,用函数MultiByteToWideChar来实现 char *ip=inet_ntoa(addrFrom.sin_addr); wchar_t *wIp=new wchar_t[100]; //比如长度100 memset(wIp,0,sizeof(wchar_t*)); MultiByteToWideChar(CP_ACP,0,ip,-1,wIp,16); //点分10进制格式地址最长也就15 //位(如"192.233.156.256"),故最后一个参数传16足够 wsprintf(tempBuf,L"%s说:%s",wIp/*ipstr*/,recvBuf); delete[] wIP; //注意释放空间
::PostMessageA(hwnd,WM_RECVDATA,0,(LPARAM)tempBuf); } return 0;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  socket unicode