Skip to content

SOCKET中宽字符问题

Published: at 04:36 AM | 2 min read

今天正在看孙鑫老师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