最近在学网络通信编程,根据书上的练习,我写了个基于Winsock编程的聊天室
但是出现了一些错误,m_addr.sin_addr.S_un.S_addr=inet_addr(m_strServer.GetBuffer(0));获取不到正确的IP地址,造成连接错误。
对话框里的建立连接按钮函数
void CExample1Dlg::OnConnect()
{
BYTE f0,f1,f2,f3;
m_ServerIp.GetAddress(f0,f1,f2,f3);
CString add;
add.Format(L"%d.%d.%d.%d",f0,f1,f2,f3);
if(m_client.InitAndConnet(m_hWnd,m_uPort,add)==FALSE)//调用下面CClient类里的InitAndConnet函数
{
return ;
}
}
BOOL CClient::InitAndConnet(HWND hwnd, UINT port, CString m_strserver)
{
m_hWnd=hwnd;
m_uPort=port;
m_strServer=m_strserver;
if(m_hSocket!=NULL)
{
closesocket(m_hSocket);
m_hSocket=NULL;
}
if(m_hSocket==NULL)
{
m_hSocket=socket(AF_INET,SOCK_STREAM,0);
ASSERT(m_hSocket!=NULL);
ClientInit();
}
//准备服务器的信息,指定服务器的地址
m_addr.sin_family=AF_INET;
m_addr.sin_addr.S_un.S_addr=inet_addr(m_strServer.GetBuffer(0));
/*在XP系统环境下,使用VS2008编译环境的 Unicode 字符集,Debug编译时,此句错误,报错为:error C2664: “inet_addr”: 不能将参数 1 从“wchar_t *”转换为“const char *” ,我将这句的类型做强制转换,m_addr.sin_addr.S_un.S_addr=inet_addr((const char *)m_strServer.GetBuffer(0));
但是转换之后,我设置的IP地址为“192.168.0.149”,而我跟踪单步调试,发现编译时获取的IP地址地址为“0.0.0.1”,是错误的。
但是直接这样赋值,编译又是对的m_addr.sin_addr.S_un.S_addr=inet_addr(“192.168.0.149“); 此问题求解中?中午未解决!!!
*/
m_addr.sin_port=htons(m_uPort);//改变端口的数据格式
int ret=0;
int error=0;
ret=connect(m_hSocket,(LPSOCKADDR)&m_addr,sizeof(m_addr));
/*char * ipaddr=NULL;
char addr[20];
in_addr inaddr;
inaddr. s_addr=2499848384;//计算机是认不出“192.168.0.149”的IP地址方式的,要经过转换变成2499848384
ipaddr= inet_ntoa(inaddr);
strcpy(addr,ipaddr);*/以上/*~~*/的内容为将2499848384的ip地址转换成这种“192.168.0.149”格式的IP地址,方便阅读。
if(ret==SOCKET_ERROR)
{
if(GetLastError()!=WSAEWOULDBLOCK)
{
AfxMessageBox(L"请确认服务器确实已经打开并工作在同样的端口!");
return false;
}
}
return TRUE;
}
最终解决办法:(下午解决此问题~/(≧▽≦)/~啦啦啦)
1.在cpp文件里面加上#include <atlbase.h> ,#pragma comment(lib, "WS2_32.lib")(网上资料说用ws2.lib库文件,但是我的VS2008编译时,老是提示此文件不存在,改成WS2_32.lib的库文件时,编译成功。)
2.在函数最前面加上USES_CONVERSION;
3.使用T2CA,m_addr.sin_addr.S_un.S_addr = inet_addr(T2CA(m_strServer.GetBuffer(0)));
即:
#include ”atlbase.h“
#pragma comment(lib, "WS2_32.lib")
//。。。。。中间的许多代码省略。。。。。。。。。。//
USES_CONVERSION;
m_addr.sin_addr.S_un.S_addr = inet_addr(T2CA(m_strServer.GetBuffer(0)));
聊天室编程在调试的时候,出现了发送的信息是乱码
跟踪调试时发现下面的这个发送消息send()函数是发送的a.GetBuffer()是多字符型,不能转换成宽字符。编译时下面函数报错:
void CClient::SendString(CString a)
{
if(send(m_hSocket,a.GetBuffer(),a.GetLength(),0)==SOCKET_ERROR)
{
AfxMessageBox(L"Client Send data error ");
}
}
报错内容为:
>正在编译...
1>Client.cpp
1>./Client.cpp(91) : error C2664: “send”: 不能将参数 2 从“wchar_t *”转换为“const char *”
1> 与指向的类型无关;转换要求 reinterpret_cast、C 样式转换或函数样式转换
///报错内容结束///
在网上找了一整天,终于找到了一份可以调试成功的资料如下:
//////////////////华丽的分割线/////////////////////////////////////////
原文章如下://开始
问题:
在用sendto函数发送信息时,代码为:
CString strSend;
GetDlgItemText(IDC_EDIT_SEND, strSend);
sendto(m_socket, strSend.GetBuffer(),strlen(charSend)+1, 0, (SOCKADDR* )&addrTo, len);
但编译后出现error:
error C2664: “sendto”: 不能将参数 2 从“wchar_t *”转换为“const char *”
在网上search解决办法,N久的恼怒后,柳暗花明找到一解决办法如下:
帖子原文:
recvfrom 的第二个参数同样是char* 的指针,但是可以直接接受WCHAR宽字符,真是生气,但生气是解决不了问题的,赶快上网找找答案吧,从MSDN到GOOGLE,经过了一小天的研究真可是又火又高兴,火的是很多人都是用自己编写的函数来解决的,可是如果那样以为简单的东西又复杂了.高兴的是吃过晚饭又继续寻找答案,最终在一个国外的网页中找到了答案,只用了3,4句就搞定了.
下面贴出来,以防再被这个问题所困扰的人:
//注意,这里的LPCSTR是不可以替换成CHAR的,否则下边会出现问题
LPCSTR pszNonUnicode;
CString strUnicode;
USES_CONVERSION;
pszNonUnicode = W2A( strUnicode.LockBuffer( ) );
//这句很关键如果没有此句,那么上边的strUnicode字符就不可以在使用了.
strUnicode.UnlockBuffer( );
然后就可以用sendto发送想要发送的内容了.
看完帖子,该代码如下,问题得以解决:
CString strSend;
GetDlgItemText(IDC_EDIT_SEND, strSend);
LPCSTR charSend;
USES_CONVERSION;
charSend = W2A( strSend.LockBuffer( ) );
sendto(m_socket, (LPCSTR)(LPCTSTR)charSend,strlen(charSend)+1, 0, (SOCKADDR* )&addrTo, len);
//文章结束
//////////////////华丽的分割线/////////////////////////////////////////
然后根据我自己写的内容,将我的代码更改如下:
void CClient::SendString(CString a)
{
LPCSTR charSend;
USES_CONVERSION;
charSend = W2A(a.LockBuffer());
a.UnlockBuffer();
if(send(m_hSocket,(LPCSTR)(LPCTSTR)charSend,a.GetLength()+1,0)==SOCKET_ERROR)
{
AfxMessageBox(L"Client Send data error ");
}
}
问题终于解决了,然后将其他的一些同样的错误按照上面的方法更改过来,我的这个基于Winsock的聊天室终于编译成功~/(≧▽≦)/~啦啦啦。在几个办公室的伙伴的共同帮忙测试下,测试也没有问题,成功!嘻~~~ 除此之外,还学到了很多字符型转换的知识,以及跟踪调试的方法。加油↖(^ω^)↗,每天学习一点点,每天进步一点点!坚持就是胜利!