winsocket send失败,返回10054

1303411 2009-10-11 11:22:51
我有一个WinSocket程序,有自己独立的线程,程序运行的时候,首先建立连接,然后调用send发送数据,紧接着调用recv接收数据,连续进行较少次数的send和recv函数的调用,没有问题,但是如果连续进行100次以上的send和recv函数调用,在第101次调用send函数时,send函数返回失败,用GetLastError得到的错误码是10054,是服务器端强制关闭了连接。

不知道在第101次调用send函数返回失败是什么原因呀?是不是和连接服务器时间过长有关呢,因为第101次调用send函数时,与服务器建立连接的时间已经有10多秒了,如果使这个原因该怎么延长连接时间呢?

还有个现象,我使用公司代理与服务器建立连接,调用send函数300多次都不会失败,是不是不使用代理时,我与服务器建立连接的方式有问题呀?

感谢大家回复。
...全文
963 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
YODOYODO 2009-10-15
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 1303411 的回复:]
引用 8 楼 yodoyodo 的回复:
如果是你开发的服务端, 那你要检查以下是不是服务端的问题, 如果不是, 那应该不是你的问题.


我也怀疑是服务器有限制,我现在的处理是如果send失败或者recv是空,那么重新和服务器建立连接,再次send和recv,测试的效果还是可以的。
[/Quote]

recv为空?? 是指的recv返回0么? 那岂不似乎说被断开了??
zj1303411 2009-10-13
  • 打赏
  • 举报
回复
接分。
1303411 2009-10-13
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 yodoyodo 的回复:]
如果是你开发的服务端, 那你要检查以下是不是服务端的问题, 如果不是, 那应该不是你的问题.
[/Quote]

服务器在日本呢!!
1303411 2009-10-13
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 yodoyodo 的回复:]
如果是你开发的服务端, 那你要检查以下是不是服务端的问题, 如果不是, 那应该不是你的问题.
[/Quote]

我也怀疑是服务器有限制,我现在的处理是如果send失败或者recv是空,那么重新和服务器建立连接,再次send和recv,测试的效果还是可以的。
1303411 2009-10-13
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 dijkstar 的回复:]
1. 是send返回的错误,还是前面的connect返回的错误;
2. 使用的select的目的是什么,是为了非阻塞吗,使用阻塞型可以放到单独的线程中,使用事件等来通信。因为对setsockopt不熟悉;
3. 尝试着将send()以后的程序注释一下试试;
4. 当出现10054时,确信服务器是否仍在正确工作?例如你可用另一台通过你说的代理连接的保持监视;
5. 强制的在for(1..500)之间加个sleep(5)试试
[/Quote]

1。向服务器发送不同的内容,会有两种错误结果,一种是send失败,lasterror是10054。一种是send成功,recv收到的是空。
2。这个是前人写的代码,我也挺疑惑为什么要使用select,我试着把select删了,代码也能正常工作,但是知识尝试了一下,不确信删了select会有什么影响,不知道大家什么意见。
3。send之后就是recv了,然后解析数据,转线程了。
4。服务器肯定在工作,但是不知道是不是服务器不让连续send和recv 101次以上。

1303411 2009-10-12
  • 打赏
  • 举报
回复
是连续send(); recv();在进行到101次的时候,或者send失败,或者recv得到的内容是空。

代码是整个一个工程,太多了,我只能贴出一部分:


int ret = WSAStartup(SOCKET_VERSION, &m_stWsData);
if (ret != 0)
{
m_iWsaError = WSAGetLastError();
}

m_stSocket = socket(PF_INET, SOCK_STREAM, 0);
if (m_stSocket == INVALID_SOCKET)
{
m_iWsaError = WSAGetLastError();
return FALSE;
}

for( ;; )
{
stSockAddr.sin_addr.s_addr = inet_addr(m_szProxyIP);
stSockAddr.sin_port = htons(m_iProxyPort);
stSockAddr.sin_family = AF_INET;

if ( ( connect( m_stSocket, (sockaddr *)&stSockAddr, sizeof(stSockAddr) ) ) )
{
m_iWsaError = WSAGetLastError();
iResult = FALSE;
break;
}

BOOL bOptval = TRUE;
setsockopt( m_stSocket, SOL_SOCKET, SO_KEEPALIVE, (char*)&bOptval, sizeof(bOptval) );

FD_ZERO( &rdevents );
FD_SET( m_stSocket, &rdevents ); //
wrevents = rdevents;
exevents = rdevents;

timeout.tv_sec = 5;
timeout.tv_usec = 0;

lRet = select( m_stSocket+1, &rdevents, &wrevents, &exevents, &timeout );
if ( lRet < 0 )
{
break;
}
else if (0 == lRet)
{
break;
}
else
{
if ( !FD_ISSET(m_stSocket, &rdevents) && !FD_ISSET(m_stSocket, &wrevents) )
{
break;
}
}

m_bConnectState = TRUE;

break;

}

for( int i = 0; i < 500; i++ )
{
if (send(m_stSocket, m_pcRequestHeader, iRequestHeaderLen+iCmdLen, 0) == SOCKET_ERROR)
{
m_iWsaError = WSAGetLastError();
return FALSE;
}

if (!getResponseHeader())
{
return FALSE;
}

//此处有线程切换,应该相当于sleep(0)了。
}
1303411 2009-10-12
  • 打赏
  • 举报
回复
我建立的连接是阻塞模式,刚才搜了一下,不知道是不是因为没有调用setsockopt导致的,具体应该是这样子:
BOOL bOptVal = TRUE;
int bOptLen = sizeof(BOOL);
setsockopt(Socket, IPPROTO_TCP, SO_KEEPALIVE, (char*)&bOptVal, bOptLen);
这样子就能延长连接的时间了?

因为我这里没有环境只能猜测了,还请高手指点呀。
dijkstar 2009-10-12
  • 打赏
  • 举报
回复
是在while中连续send吗?是的话,应该之间Sleep()个2~3毫秒。另外,应该把出问题的那部分程序贴出来看看
1303411 2009-10-12
  • 打赏
  • 举报
回复
刚才试了,使用setsockopt函数问题仍然再现,难道是服务器端有这样的限制,麻烦高手帮帮忙呀。
YODOYODO 2009-10-12
  • 打赏
  • 举报
回复
如果是你开发的服务端, 那你要检查以下是不是服务端的问题, 如果不是, 那应该不是你的问题.
YODOYODO 2009-10-12
  • 打赏
  • 举报
回复
10054是连接被重置

from msdn:

10054
WSAECONNRESET
Connection reset by peer. An existing connection was forcibly closed by the remote host. This normally results if the peer application on the remote host is suddenly stopped, the host is rebooted, or the remote host uses a hard close (see setsockopt (Windows Sockets) for more information on the SO_LINGER option on the remote socket.) This error may also result if a connection was broken due to keep-alive activity detecting a failure while one or more operations are in progress. Operations that were in progress fail with WSAENETRESET. Subsequent operations fail with WSAECONNRESET.
ssm1984119 2009-10-12
  • 打赏
  • 举报
回复
这种问题很明显不是客户端程序的问题,我也遇到过。有一种可能是服务器端不允许客户端太频繁的操作,我遇到的就是这种情况;或者是网络通路,数据在中间经过很多路由后发生了变化,服务器拒绝接收。
dijkstar 2009-10-12
  • 打赏
  • 举报
回复
1. 是send返回的错误,还是前面的connect返回的错误;
2. 使用的select的目的是什么,是为了非阻塞吗,使用阻塞型可以放到单独的线程中,使用事件等来通信。因为对setsockopt不熟悉;
3. 尝试着将send()以后的程序注释一下试试;
4. 当出现10054时,确信服务器是否仍在正确工作?例如你可用另一台通过你说的代理连接的保持监视;
5. 强制的在for(1..500)之间加个sleep(5)试试

18,363

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧