今天正在看孙鑫老师vc++16课的一个聊天程序视频教程,按照上面做了一下但遇到两个小的问题,最后解决了所以记录下。 当你的编译器用的是unicode字符集的话就会出现我遇到的这两个问题。
从ip地址控件上获取的值经过inet_ntoa转换为网络字节序后在接收端显示的时候是乱码
LRESULT CMFCCHATDlg::OnSock(WPARAM wParam, LPARAM lParam)
{
switch (LOWORD(lParam))
{
case FD_READ:
WSABUF wsabuf;
wsabuf.buf = new CHAR[218];
wsabuf.len = 218;
DWORD dwRead;
DWORD dwFlag = 0;
SOCKADDR_IN addrFrom;
int len = sizeof(SOCKADDR);
if (SOCKET_ERROR == WSARecvFrom(m_socket, &wsabuf, 1, &dwRead, &dwFlag,
(SOCKADDR*)&addrFrom, &len, NULL, NULL))
{
MessageBox(L"接受数据失败!");
return 0;
}
CString str, strTemp;
char *szFromIp = inet_ntoa(addrFrom.sin_addr);
wchar_t wszFromIp[64] = {0};
MultiByteToWideChar(CP_ACP, 0, szFromIp, strlen(szFromIp), wszFromIp, 64<<1); // 将其转换为宽字符的就可以了
str.Format(L"%s say: %s", wszFromIp, wsabuf.buf);
str += L"/r/n";
GetDlgItemText(IDC_EDIT_RECV, strTemp);
str += strTemp;
SetDlgItemText(IDC_EDIT_RECV, str);
break;
default:
break;
}
return 1;
}
WSABUF中的buf只能接受char*, 而我们获取的是wchar_t
void CMFCCHATDlg::OnBnClickedBtnSend()
{
// TODO: Add your control notification handler code here
DWORD dwIp;
LPTSTR lpSend;
WSABUF wsabuf;
DWORD dwSend;
//int len;
((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1))->GetAddress(dwIp);
SOCKADDR_IN addrTo;
addrTo.sin_addr.S_un.S_addr = htonl(dwIp);
addrTo.sin_family = AF_INET;
addrTo.sin_port = htons(6000);
lpSend = new wchar_t[218];
GetDlgItemText(IDC_EDIT_SEND, lpSend, 218);
//len = strSend.GetLength();
//wsabuf.buf = strSend.GetBuffer(len);
wsabuf.buf = (CHAR*)lpSend; //不用CString,直接这里强制转换一下
wsabuf.len = (wcslen(lpSend) + 1) * sizeof(wchar_t);
SetDlgItemText(IDC_EDIT_SEND, L"");
if (SOCKET_ERROR == WSASendTo(m_socket, &wsabuf, 1, &dwSend, 0,
(SOCKADDR*)&addrTo, sizeof(SOCKADDR), NULL, NULL))
{
MessageBox(L"发送数据失败!");
delete lpSend;
return;
}
delete lpSend;
}
感觉这两个方法都不太好,不知道SOCKET有没有对应的宽字符处理函数, 就像(strlen, wcslen), SOCKET方面我还是小白知道的不多, 以后多多努力。
2011-06-05