首页 > 编程知识 正文

linux wait函数,recv函数返回值

时间:2023-05-05 13:21:15 阅读:167404 作者:761

为什么在linux上调用recv函数,并且死循环位于recv函数中?

linux服务器在只有1000个连接时一切正常,在连接到2000个以上之前,在recv函数中呈死循环,cpu占有率高。 因为recv是系统函数,所以也不知道他在qldhn上做什么。 程序通过epoll实现了。 有谁遇到过类似的问题吗? 还是可以指导努力的方向呢? 返回一层:在建立连接时跑了一会儿,而不是死循环,然后调用recv函数时。 这里是服务器。 接受连接。 一个进程有多个线程。 为每个线程管理多个连接。 各线程使用epoll方式响应网络事件,在网络可读的情况下调用recv函数读取数据。 在进行测试的过程中,发现1000个连接很好。 如果是3000个连接,跑了一夜后,有几个线程在重复系统的recv函数。 回到二楼:调试有问题的程序后,我们发现有一些线程停留在recv函数中。 执行n步后,直接跳出此线程。 所谓死循环,是因为在这些情况下这些相关线程的cpu占有率很高。 既然套接字已经违法了,该如何尽早避免处理? 回到三楼:插座都是无阻塞的。

更新时间: 2019-05-19 19:50

最满意的回答

我们建议您在strace中看看那几个线程准确地卡在了哪里

而且你描述的是死循环。 recv函数为什么要死循环?

之后,当zjdwdm的系统压力增大时,epoll指示某个套接字可以使用,但在进行读取时该套接字被关闭。 看看这种情况会不会影响程序。

请参见------------------------------------------------------- -

man recv

RETURN VALUE

thesecallsreturnthenumberofbytesreceived,or-1 ifanerroroccurred.thereturnvaluewillbe0whentheperhasperformedan

订单关闭。

如您所见,如果端到端关闭套接字,recv的返回值将为0。 作为你的程序,你没有判断这种情况吗? 如果你缺省使用的是EPOLLET模式,你一定会继续阅读套接字直到EAGAIN出现,但是如果返回值0,EAGAIN就不会出现。

建议使用strace来调查问题。 在某些情况下,比gdb更能直接确定原因。

在、

再修改一点,recv是linux系统调用,屏蔽还是返回没有死循环问题。 死循环一定出现在你的程序代码中。 如果您认为recv本身并没有结束,而是占用了大量的cpu,那么linux库就会出现错误,或者内核有错误。

2009-12-30答复

其他回答

send后,OS决定是否是马山建设,还是有其他send,将他们一起打包发送。 所以你recv不知道会收多少个包。

2009-12-31答复

将recv ()设置为timeout,超过此时间后将返回超时错误。 请不要让recv保持被阻止在那里。

timeout可以自己做。

以下是谷歌制作的例子。

struct timeval tv;/* timevalandtimeoutstuffaddedbydavekw 7x * /

int timeouts=0;

tv.tv_sec=3;

tv.tv_usec=0;

if(setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,(char * ) tv,sizeof tv ) )

{

perror(setsockopt );

返回- 1;

}

connect (sockfd,) struct sockaddr * ) their_addr,sizeof their_addr )=-1 ) {

perror (连接);

exit(1;

}

while () ) numbytes=recv(sockfd,buf,max datasize-1,0 ) )=-1 ) (timeouts 1000 )/* looptoretryincaseitttiming ang

perror(recv );

打印(after time out # % d,trying again:n ),timeouts );

}

printf('numbytes=%dn ',numbytes );

buf[numbytes]=' ';

printf (接收的: % s )、buf );

2009-12-31答复

答疑

我建议你在strace上看看那几个线程准确地卡在哪里

你描述的是,死循环。 recv函数怎么会死循环? 还有,zjdwdm的系统压力变大的时候, 会出现epoll提示某socket可用,但是等你去读的时候该socket已经被关闭的情况,你看看这种情况会不会对你的程序造成影响。 ---------------------------- man recv RETURN VALUE These calls return the number of bytes received, or -1 if an error

...

recv是socket编程中最常用的函数之一,在阻塞状态的recv有时候会返回不同的值,而对于错误值也有相应的错误码,分别对应不同的状态,下面是我针对常见的几种网络状态的简单总结。 首先阻塞接收的recv有时候会返回0,这仅在对端已经关闭TCP连接时才会发生。 而当拔掉设备网线的时候,recv并不会发生变化,仍然阻塞,如果在这个拔网线阶段,socket被关掉了,后果可能就是recv永久的阻塞了。 所以一般对于阻塞的socket都会用setsockopt来设置recv超时。 当超时时间到达后,rec

...

建议你用strace看那几个线程确切是卡在哪里 而且你描述的是,死循环。 recv函数怎么会死循环? 还有,zjdwdm的系统压力变大的时候, 会出现epoll提示某socket可用,但是等你去读的时候该socket已经被关闭的情况,你看看这种情况会不会对你的程序造成影响。 ---------------------------- man recv RETURN VALUE These calls return the number of bytes received, or -1 if an error

...

您可以使用setsockopt函数在接收操作上设置超时: SO_RCVTIMEO 设置超时值,指定输入函数等待直到完成的最大时间量。 它接受时间结构,秒数和微秒数指定等待输入操作完成的时间限制。 如果接收操作在没有接收到附加数据的情况下阻塞了这么多时间,则如果没有接收到数据,则它将返回部分计数或errno设置为[EAGAIN]或[EWOULDBLOCK]。 该选项的默认值为零,表示接收操作不会超时。 此选项需要一个时间结构。 请注意,并非所有实现都允许设置此选项。 // LINUX

struct

...

recv()在流的末尾返回零,这在对等体关闭连接时发生。 关于它没有任何“随机”。 recv() returns zero at end of stream, which in turn occurs when the peer closes the connection. There is nothing 'random' about it.

你有多确定segfault是在recv() ? 您对recv()调用看起来很好,但是,之前的一行是写入未分配的内存,这将导致段错误: std::cin >> tempString;

尝试像这样声明tempString : #define INPUT_BUF_SIZE 100

char tempString[INPUT_BUF_SIZE + 1];

此外,这段代码似乎不寻常: echoStringLen = strlen(echoString); /* Determine in

...

忘了将此标记为已解决。 所有套接字实例都从套接字基类继承其文件描述符变量。 TCPSocket类有一个重载的fd var,它被设置而不是基本的fd。 Forgot to 自信的龙猫 this as solved. All socket instances inherit their file descriptor vars from a socket base class. The TCPSocket class had an overloaded fd var that was getting s

...

您希望shutdown(fd, SHUT_WR)仅关闭写入但仍能够读取。 close(fd)将使文件描述符无效,就像关闭了本地文件的开放路径一样。 http://man7.org/linux/man-pages/man2/shutdown.2.html You want shutdown(fd, SHUT_WR) to close only for writes but still be able to read. close(fd) will invalidate the file descri

...

C ++代码中的许多错误 - 比如if (bytesSent = 0) ,这是一个结果转换为boolean的赋值,所以总是返回false 。 您不注意从TCP套接字读取的字节数,假设您在发送时收到一条完整的消息 - 这是错误的,因为您可能正在阅读部分消息,多于一条消息或介于两者之间的任何内容 - 它是一个原始字节流 。 检查-1显式返回系统调用,然后检查errno(3)的值,比如说strerror(3)函数来找出出错的地方。 编辑0: 您正在尝试使用侦听套接字sSock进行数据传输 - 错误 -

...

如果通信中发生错误,则会在套接字上设置错误,并与下一个与套接字相关的系统调用一起传递。 EHOSTUNREACH错误可以(通过其他方式)通过向目标发送UDP数据包并使ICMP无法访问来触发。 由于此ICMP消息仅在send调用完成后才返回,因此它不会返回send而只返回到套接字上的下一个系统调用,也可能是一个recv 。 因此我建议在Linux中也可以返回此错误,但我可能错了。 通常Linux不是UNIX,系统发展和文档通常是有缺陷的。 如果你在各种平台上查看recv的文档,你会发现OpenBSD

...

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。