多线程的socket 客户端 总是接收不到
时间:2011-12-15
来源:互联网
客户端是一个dll,程序通过多线程调用dll里的函数向服务器发送数据,
现在发现 线程只有一个 偶尔有两个返回调用成功,其它的在接收数据的时候就发生错误了,但是数据已经都发出去了 。
SOCKET fSocket::Connect(char *szIP,UINT nPort)
{
SOCKET hSocket = INVALID_SOCKET;
clock_t start,ends;
//没有初始化,则要重新初始化
if (!m_SocketInstalled ) return INVALID_SOCKET;
//测试网络是否畅通
if (!Ping(szIP))
{
TRACE(_T("Ping failed\n"));
closesocket(hSocket);
hSocket = INVALID_SOCKET;
return hSocket;
}
start = clock();
ends = clock();
//创建SOCKET
while ((hSocket == INVALID_SOCKET) && ((ends - start)<m_szTimeOut))
{
if ((hSocket=socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
TRACE(_T("Create socket failed\n"));
hSocket = INVALID_SOCKET;
return hSocket;
}
ends = clock();
}
if (hSocket == INVALID_SOCKET)
return hSocket;
SetTimeOut(hSocket,m_szTimeOut);
linger m_sLinger;
m_sLinger.l_onoff = 1; // (在closesocket()调用,但是还有数据没发送完毕的时候容许逗留)
m_sLinger.l_linger = 0; // (容许逗留的时间为0秒)
u_long ul =1;
setsockopt(hSocket,SOL_SOCKET,SO_LINGER,(char*)&m_sLinger,sizeof(linger));
//填充 client struct
struct sockaddr_in addr;
ZeroMemory((char *)&addr,sizeof(addr));
CopyMemory((char *)&(addr.sin_addr),(char *)&serveraddr,sizeof(addr.sin_addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(nPort);
// unsigned long ul=1;
if (connect(hSocket,(struct sockaddr *)&addr,sizeof(addr)) == SOCKET_ERROR)
{
DisConnect(hSocket);
TRACE(_T("connect failed\n"));
hSocket = INVALID_SOCKET;
return hSocket;
}
return hSocket;
}
BOOL fSocket::RecvData(SOCKET hSocket,LPVOID lpData,short nSize)
{
if (hSocket == INVALID_SOCKET) return false;
int nLen,nRet,nError;
fd_set fds;
clock_t tmStart,tmEnd;
CString str;
//设置检测状态,等待时间为1秒
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec= 0;
tmStart = clock();
nLen = 0;
while(nLen < nSize)
{
//检测侦听SOCKET的状态
FD_ZERO(&fds);
FD_SET(hSocket,&fds);
nError=::select((int)hSocket+1,&fds,NULL,NULL,&timeout);
//发生错误
if (nError == SOCKET_ERROR)
{
TRACE(_T("Recv select = SOCKET_ERROR"));
//断开连接
DisConnect(hSocket);
return false;
}
//无数据
if (nError == 0)
{
tmEnd = clock();
if (m_szTimeOut > 0 && ((tmEnd - tmStart) >= m_szTimeOut))
{
//
TRACE(_T("Recv select = 0 "));
DisConnect(hSocket);
return false;
}
else continue;
}
if (FD_ISSET(hSocket, &fds))
{
nRet = ::recv(hSocket,(char *)lpData+nLen,nSize-nLen,0);
if (nRet == SOCKET_ERROR)
{
TRACE(_T("recv = SOCKET_ERROR"+ str));
return false;
}
nLen += nRet;
}
}
return true;
}
其它的线程总是 提示 Recv select = 0
服务器端显示 要发送多少数据 已经发送0 。
对 c++不太懂 ,大家帮帮忙
现在发现 线程只有一个 偶尔有两个返回调用成功,其它的在接收数据的时候就发生错误了,但是数据已经都发出去了 。
SOCKET fSocket::Connect(char *szIP,UINT nPort)
{
SOCKET hSocket = INVALID_SOCKET;
clock_t start,ends;
//没有初始化,则要重新初始化
if (!m_SocketInstalled ) return INVALID_SOCKET;
//测试网络是否畅通
if (!Ping(szIP))
{
TRACE(_T("Ping failed\n"));
closesocket(hSocket);
hSocket = INVALID_SOCKET;
return hSocket;
}
start = clock();
ends = clock();
//创建SOCKET
while ((hSocket == INVALID_SOCKET) && ((ends - start)<m_szTimeOut))
{
if ((hSocket=socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
TRACE(_T("Create socket failed\n"));
hSocket = INVALID_SOCKET;
return hSocket;
}
ends = clock();
}
if (hSocket == INVALID_SOCKET)
return hSocket;
SetTimeOut(hSocket,m_szTimeOut);
linger m_sLinger;
m_sLinger.l_onoff = 1; // (在closesocket()调用,但是还有数据没发送完毕的时候容许逗留)
m_sLinger.l_linger = 0; // (容许逗留的时间为0秒)
u_long ul =1;
setsockopt(hSocket,SOL_SOCKET,SO_LINGER,(char*)&m_sLinger,sizeof(linger));
//填充 client struct
struct sockaddr_in addr;
ZeroMemory((char *)&addr,sizeof(addr));
CopyMemory((char *)&(addr.sin_addr),(char *)&serveraddr,sizeof(addr.sin_addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(nPort);
// unsigned long ul=1;
if (connect(hSocket,(struct sockaddr *)&addr,sizeof(addr)) == SOCKET_ERROR)
{
DisConnect(hSocket);
TRACE(_T("connect failed\n"));
hSocket = INVALID_SOCKET;
return hSocket;
}
return hSocket;
}
BOOL fSocket::RecvData(SOCKET hSocket,LPVOID lpData,short nSize)
{
if (hSocket == INVALID_SOCKET) return false;
int nLen,nRet,nError;
fd_set fds;
clock_t tmStart,tmEnd;
CString str;
//设置检测状态,等待时间为1秒
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec= 0;
tmStart = clock();
nLen = 0;
while(nLen < nSize)
{
//检测侦听SOCKET的状态
FD_ZERO(&fds);
FD_SET(hSocket,&fds);
nError=::select((int)hSocket+1,&fds,NULL,NULL,&timeout);
//发生错误
if (nError == SOCKET_ERROR)
{
TRACE(_T("Recv select = SOCKET_ERROR"));
//断开连接
DisConnect(hSocket);
return false;
}
//无数据
if (nError == 0)
{
tmEnd = clock();
if (m_szTimeOut > 0 && ((tmEnd - tmStart) >= m_szTimeOut))
{
//
TRACE(_T("Recv select = 0 "));
DisConnect(hSocket);
return false;
}
else continue;
}
if (FD_ISSET(hSocket, &fds))
{
nRet = ::recv(hSocket,(char *)lpData+nLen,nSize-nLen,0);
if (nRet == SOCKET_ERROR)
{
TRACE(_T("recv = SOCKET_ERROR"+ str));
return false;
}
nLen += nRet;
}
}
return true;
}
其它的线程总是 提示 Recv select = 0
服务器端显示 要发送多少数据 已经发送0 。
对 c++不太懂 ,大家帮帮忙
作者: ar996 发布时间: 2011-12-15
刚毕业
导师安排熟悉socket,关注下。。
导师安排熟悉socket,关注下。。
作者: jaynaviee 发布时间: 2011-12-16
要在服务器端程序找原因,对方收到后处理的逻辑有问题
作者: xqlu2007 发布时间: 2011-12-17
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28