Linux CentOS 5:非阻塞套接字发送独立挂起 我在Linux中有以下C++代码: if (epoll_wait(hEvent,&netEvents,1,0)) { // check FIRST for disconnection to avoid send() to a closed socket (halts on centos on my server!) if ((netEvents.events & EPOLLERR)||(netEvents.events & EPOLLHUP)||(netEvents.events & EPOLLRDHUP)) { save_log("> client terminated connection"); goto connection_ended; // ---[ if its a CLOSE event .. close :) } if (netEvents.events & EPOLLOUT) // ---[ if socket is available for write { if (send_len) { result = send(s,buffer,send_len,MSG_NOSIGNAL); save_slogf("1112:send (s=%d,len=%d,ret=%d,errno=%d,epoll=%d,events=%d)",s,send_len,result,errno,hEvent,netEvents.events); if (result > 0) { send_len = 0; current_stage = CL_STAGE_USE_LINK_BRIDGE; if (close_after_send_response) { save_log("> destination machine closed connection"); close_after_send_response = false; goto connection_ended; } } else { if (errno == EAGAIN) return; else if (errno == EWOULDBLOCK) return; else { save_log("> unexpected error on socket, terminating"); connection_ended: close_client(); reset(); return; } } } } } }

Linux CentOS 5:非阻塞套接字发送独立挂起 我在Linux中有以下C++代码: if (epoll_wait(hEvent,&netEvents,1,0)) { // check FIRST for disconnection to avoid send() to a closed socket (halts on centos on my server!) if ((netEvents.events & EPOLLERR)||(netEvents.events & EPOLLHUP)||(netEvents.events & EPOLLRDHUP)) { save_log("> client terminated connection"); goto connection_ended; // ---[ if its a CLOSE event .. close :) } if (netEvents.events & EPOLLOUT) // ---[ if socket is available for write { if (send_len) { result = send(s,buffer,send_len,MSG_NOSIGNAL); save_slogf("1112:send (s=%d,len=%d,ret=%d,errno=%d,epoll=%d,events=%d)",s,send_len,result,errno,hEvent,netEvents.events); if (result > 0) { send_len = 0; current_stage = CL_STAGE_USE_LINK_BRIDGE; if (close_after_send_response) { save_log("> destination machine closed connection"); close_after_send_response = false; goto connection_ended; } } else { if (errno == EAGAIN) return; else if (errno == EWOULDBLOCK) return; else { save_log("> unexpected error on socket, terminating"); connection_ended: close_client(); reset(); return; } } } } } },c++,linux,sockets,linux-kernel,nonblocking,C++,Linux,Sockets,Linux Kernel,Nonblocking,hEvent:epoll创建用于侦听EPOLLIN、EPOLLOUT、EPOLLERR、EPOLLHUP、EPOLLRDHUP s:非阻塞(!!!)套接字是从非阻塞侦听套接字上的接受创建的 基本上,这段代码试图将数据包发送回连接到服务器的已连接用户。它通常工作正常,但在随机的情况下(可能是当一些无线网络事件发生时),程序无限期挂起在“result=send(s,buffer,send_len,MSG_NOSIGNAL)”行上 我不知道这可能是什么原因,我曾尝试监控套接字操作,但似乎没有任何线索告

hEvent:epoll创建用于侦听EPOLLIN、EPOLLOUT、EPOLLERR、EPOLLHUP、EPOLLRDHUP

s:非阻塞(!!!)套接字是从非阻塞侦听套接字上的接受创建的

基本上,这段代码试图将数据包发送回连接到服务器的已连接用户。它通常工作正常,但在随机的情况下(可能是当一些无线网络事件发生时),程序无限期挂起在“result=send(s,buffer,send_len,MSG_NOSIGNAL)”行上


我不知道这可能是什么原因,我曾尝试监控套接字操作,但似乎没有任何线索告诉我为什么会发生这种情况。我必须假设这是一个内核错误或非常怪异的东西,因为我在Windows下编写了相同的程序,并且它在那里工作得非常完美。

你必须明确地做出's'非阻塞如果您没有这样做,它不会从侦听套接字继承非阻塞性。我尝试通过添加“fcntl(socket,F_SETFL,flags | O_NONBLOCK);“在由accept()创建的接受套接字上,但现在发送回客户端的信息似乎已损坏(我正在发送FLV文件流..在添加此fcntl之前工作正常)…为什么会这样?在非阻塞模式下,发送()是正常行为。”管理发送的数据比您要求的要少,而recv()管理接收的数据比您要求的要少。您必须使用缓冲区才能正确发送/接收数据。据您所知,recv()可以一次给你一个字节。哇,你是对的。刚刚检查了我的日志,发送的字节比输入的字节少。多谢!这总是你的错。不是内核错误,不是编译器错误。它是你的bug。你可以考虑使用像Boost。Asio这样的测试和验证框架,它也是交叉PL。atform和将在Windows上很好地工作。