线程不更新但阻塞recv()

时间:2015-05-09 02:53:48

标签: c multithreading sockets tcp recv

我正在创建一个多线程TCP服务器,当我在线程中使用recv()时,它们不会无限更新/执行/运行(循环),除非recv()实际接收到一些数据。

这是循环内部的代码片段。

if( seconds < 15 ){
    printf("%f seconds passed: \r", seconds);

    if ( (read_size = recv(sock , client_message , 512 , 0)) > 0 )
    {
      //Send the message back to client
      reply_message = client_message;
      (void)write(sock, reply_message, strlen(reply_message));
    }

}else{
    // ... blah blah blah
}

如果我注释掉内部IF语句,则该线程运行&amp;尽可能快地输出printf()。当包含IF语句时,线程等待recv()并且不会更新(printf()没有打印),直到recv()收到数据:/

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

来自recv(2) - Linux手册页(见here):

  

如果套接字上没有可用消息,则接收呼叫等待   要到达的消息,除非套接字是非阻塞的(参见fcntl(2)),   在这种情况下,返回值-1和外部变量errno   设置为EAGAIN或EWOULDBLOCK。接收呼叫通常会返回任何呼叫   数据可用,达到要求的数量,而不是等待   收到所要求的全额。

这就是recv的工作方式。如果您希望立即返回,则应使用非阻止模式(请参阅fcntlselect desriptions)。

// sock is the socket you want to make non-blocking
int status = fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK);

// handle the error
if(status == -1) {
    ...
}

如果你想检查套接字中是否有任何东西要读

int count = 0;
ioctl(sock, FIONREAD, &count);

count是套接字中可用的字节数