我封装了套接字,执行获取网页源码的功能我采取的是tcp协议,阻塞模式的。这个是我自己定义初始化socket以及连接主机、端口的函数(没问题)bInitSocket(CString pHost,//主机,域名
int nPort)//端口号
{
//...
//连接服务器
if (connect(m_Socket, (sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
MessageBox(NULL, "Connect Error!", "Error", 0);
CloseSocket();
return FALSE;
}
//...
}
这个是我自己封装的发送包的方法(没问题)nPostPackage(const CString strPockage)
{
//....
//发送数据
nSend = send(m_Socket, strNewPockage.GetBuffer(0), strNewPockage.GetLength(), 0);
//...
}
这个是我自己封装的在调用nPostPackage方法后执行接收数据的方法(没问题)nGetData()
{
while (nRet > 0)
{
//...
// 接收返回数据包
nRet = recv(m_Socket, (LPSTR)arryRecv, sizeof(arryRecv), 0);
//...
}
{}
这个是我自己封装的关闭套接字的方法(没问题)CloseSocket()
{
try
{
shutdown(m_Socket, 0X02);
closesocket(m_Socket);
WSACleanup();
}
catch (...)
{
MessageBox(NULL, "Close socket fail", "Error", 0);
}
}**************************
接下来就是我的问题。
我循环(当循环第一次就能nPostPackage和nGetData成功,但是循环第二次的时候就会nGetData返回0个数据){
nPostPackage(const CString strPockage);//发送数据包后
nGetData();//接收数据
}
然后我修改成(这个就能成功执行完所有我的循环){
bInitSocket(CString pHost,//主机,域名
int nPort);//端口号//初始化并且连接服务器
nPostPackage(const CString strPockage);//发送数据包后
nGetData();//接收数据
CloseSocket();//关闭套接字
}
问题一:为什么修改成这样之后才能成功?
问题二:因为每循环一次都需要连接和关闭套接字,这样性能急剧下降,有没有什么好的办法可以解决此处的性能问题?我只想使用同一个套接字对象,不想创建多个套接字对象。谢谢。
int nPort)//端口号
{
//...
//连接服务器
if (connect(m_Socket, (sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
MessageBox(NULL, "Connect Error!", "Error", 0);
CloseSocket();
return FALSE;
}
//...
}
这个是我自己封装的发送包的方法(没问题)nPostPackage(const CString strPockage)
{
//....
//发送数据
nSend = send(m_Socket, strNewPockage.GetBuffer(0), strNewPockage.GetLength(), 0);
//...
}
这个是我自己封装的在调用nPostPackage方法后执行接收数据的方法(没问题)nGetData()
{
while (nRet > 0)
{
//...
// 接收返回数据包
nRet = recv(m_Socket, (LPSTR)arryRecv, sizeof(arryRecv), 0);
//...
}
{}
这个是我自己封装的关闭套接字的方法(没问题)CloseSocket()
{
try
{
shutdown(m_Socket, 0X02);
closesocket(m_Socket);
WSACleanup();
}
catch (...)
{
MessageBox(NULL, "Close socket fail", "Error", 0);
}
}**************************
接下来就是我的问题。
我循环(当循环第一次就能nPostPackage和nGetData成功,但是循环第二次的时候就会nGetData返回0个数据){
nPostPackage(const CString strPockage);//发送数据包后
nGetData();//接收数据
}
然后我修改成(这个就能成功执行完所有我的循环){
bInitSocket(CString pHost,//主机,域名
int nPort);//端口号//初始化并且连接服务器
nPostPackage(const CString strPockage);//发送数据包后
nGetData();//接收数据
CloseSocket();//关闭套接字
}
问题一:为什么修改成这样之后才能成功?
问题二:因为每循环一次都需要连接和关闭套接字,这样性能急剧下降,有没有什么好的办法可以解决此处的性能问题?我只想使用同一个套接字对象,不想创建多个套接字对象。谢谢。
每次操作以后服务器close了这个连接
close以后宣告这个连接失效
send(),send(),recv(),recv()还是send(),recv(),send(),recv()?
如果是前者,可能第一次recv()就把两次send的都接收的。如果不是这个问题,可以查看一下,第一次recv是不是send的长度。第二次send是否成功;成功,send的长度。问题可以一步一步分析
{
while (true)
{
//...
// 接收返回数据包
int nRet = recv(m_Socket, (LPSTR)arryRecv, sizeof(arryRecv), 0);
//...
if(nRet > 0)
{
//todo
}
else()
{}
}
{}
同理,recv之后,包头前四个字节可以表示为int,与recv的长度进行比较。
要知道,一个连接,除了你自己close以外, 服务器也是可以close的。
你返回0,说明就是服务器已经close了啊,所以你必须重新连接。至于为何服务器会主动close, 你没有说你连的是什么服务器,说以不好说。
如果你连的是HTTP网站,正如cl_gamer所说,HTTP服务器在给你返回数据后,就会close连接。