winsock错误,代码10055,怎么回是?

julien_lee 2001-07-04 02:11:42
我写了一个通讯网关,类似于一个管道,从一头获取某类请求,再根据请求内容发往不同的目的地,然后等目的地回包,若成功回包,简单地将回包信息发回给请求者,否则,给请求者发回一个错误信息。
由于请求的随机性及大量性,我做成了多线程,具体做法是,来一个请求,起一个线程,然后所有的create sock, connect, send, recv ,shutdown, close 动作都在线程内部完成。
但是奇怪的是,系统运行一段时间之后,整个程序就死掉了,查相应log,可以发现最后的错误代码是10055,这是怎么回事,难道我关闭socket不成功吗?但是log里几乎所有的信息都是显示成功,只不过最后的少许信息显示了10055,但是要知道,socket的可用句柄个数可有65535个至多喔,实在不明白。
简化后的关键性代码如下:
void MyThreadProc(LPVOID pParam)
{
........
SOCKET local_socket;
sockaddr_in remote_sockaddr;
int ErrorCode;
local_socket=::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(local_socket==INVALID_SOCKET)
{
//write create socke error log here.
goto END;
}

int flag=1;
setsockopt( local_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(BOOL));
setsockopt( local_socket, SOL_SOCKET, SO_DONTLINGER, (char *)&flag, sizeof(BOOL));

remote_sockaddr=pSubGateInfo->SockAddr;
res=::connect(local_socket,(SOCKADDR*)&remote_sockaddr,sizeof(remote_sockaddr));
if(res==SOCKET_ERROR)
{
//write connect error log here.
goto END;
}

if(::send(local_socket,sendmsg,strlen(sendmsg),0)<0)
{
//write send msg error log here.
goto END;
}

::memset(recvmsg,'\0',sizeof(recvmsg));
if(::recv(local_socket,recvmsg,4,0)<0)
{
//write recv head info error here
goto END;
}

datalen=atoi(recvmsg);
::memset(recvmsg,'\0',sizeof(recvmsg));
if(::recv(local_socket,recvmsg,datalen,0)<0)
{
//write recv msg error here
goto END;
}

//recv from remote successfully!
//do what i really wanna to do.........
END:
if(::shutdown(local_socket,2)==SOCKET_ERROR)
{
//write shutdown sock error here
}

if(::closesocket(local_socket)==SOCKET_ERROR)
{
//write close sock error here
}
local_socket=INVALID_SOCKET;
delete pMsg;
}

请各位大虾不吝赐教!
...全文
715 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
lpt 2001-07-04
  • 打赏
  • 举报
回复
同意楼上的
nilm 2001-07-04
  • 打赏
  • 举报
回复
我想给你个建议,你程序这样的结构不是很好,线程的创建,释放,切换的系统开销很大。不妨用几个线程做这个事,这些线程一直运行着,这样也不必每次CREATE 、CONNECT、 SHUTDOWN SOCKET 了。 将请求和应答排队,线程从请求队列取请求,处理完了放到应答队列。。。。
colin08 2001-07-04
  • 打赏
  • 举报
回复
我不是程序员,但我遇到过这样的情况,Down 了一个WINSOCK2升级了一下就行了!不妨试试!
gop 2001-07-04
  • 打赏
  • 举报
回复
发送的速度太快,使协议栈的缓冲区满.

发慢一点吗!

当然,可能是缓冲被设得太小了
xlqin 2001-07-04
  • 打赏
  • 举报
回复
就是线程太多,每个线程者用到一定的缓冲,最后不就不够了
abnegate 2001-07-04
  • 打赏
  • 举报
回复
BUG: Send() Fails with Error WSAENOBUFS Over Blocking Socket
When large blocks of data (for example, 3-4 MB) are sent over a blocking socket, send eventually fails with error 10055, WSAENOBUFS.
abnegate 2001-07-04
  • 打赏
  • 举报
回复
WSAENOBUFS 10055 No buffer space available.
julien_lee 2001-07-04
  • 打赏
  • 举报
回复
谢谢nilm()的建议。您的做法是标准的worker thread做法。并不是我没有想到,而是由于我们业务的特殊性,无法使用您提议的worker thread做法。
我以前就是使用的nilm()的做法,预先起好30个线程,并睡眠等待业务的到来,主线程接受业务,并轮循地提交给30个worker之一,并将该worker唤醒。
worker被唤醒之后,循环读自己的业务队列,并一一处理直至处理完毕。然后再次将自己悬挂起来。
这样处理如果通讯情况良好时是没有什么问题。但是可以想象那样一种情况(而且是很容易出现的一种情况):一个请求进入了某一个worker的业务队列,然后被该worker处理,但是不幸的是,该业务属于棘手业务,通讯回包时间不可预料,这时候又有一个业务轮循进入了该worker的业务队列,那么即使本业务属于较容易处理业务,也会由于前面业务的阻拦,导致不得不等待。正所谓“一粒老鼠屎,搅坏一锅汤”.
当然可以考虑优化,如抛弃简单轮循算法,采取较复杂的最段业务队列算法,或者更复杂些,采取业务优先级调度算法,是可以极大地避免此类问题,但是那样以来,系统代码复杂,而且也不能从根本上解决此类问题。而我的来一个请求,开一个线程,就可以完全避免这一类问题的发生,而且系统代码非常简单。
我现在的问题是,我的代码是不是会导致socket关闭不成功,从而耗尽系统资源呢?
azuo_lee 2001-07-04
  • 打赏
  • 举报
回复
10055错误是系统队列或缓冲区满,与socket句柄的多少无关。可能是由于你开的线程太多,代码又不够优化,导致系统资源耗尽而引起的。

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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