【问题标题】:Thread not updating but blocking on recv()线程不更新但在 recv() 上阻塞
【发布时间】:2015-07-20 01:18:51
【问题描述】:

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

这是循环内部的代码 sn-p。

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 语句,线程会尽可能快地运行并输出 printf()。当包含 IF 语句时,线程在 recv() 上等待并且在 recv() 接收到数据之前不会更新( printf() 不打印):/

有什么想法吗?

【问题讨论】:

  • 这就是它应该做的。你期待它做什么?
  • 它应该在接收数据的同时连续打印出最多 15 秒的秒数。但是,当使用 recv() 时,它不会,并且其他基于 seconds 变量的条件语句不会执行,因为 recv() 会暂停线程。
  • 您想将selectrecv 结合使用1 秒超时。您还想将套接字设置为非阻塞。您还需要处理短读...
  • 'recv() 停止[你的意思是'阻塞']线程'是应该发生的。你的问题还不清楚。

标签: c multithreading sockets tcp recv


【解决方案1】:

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

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

这就是recv 的工作方式。如果您希望它立即返回,您应该使用非阻塞模式(参见 fcntlselect 说明)。

// 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 是套接字中可用的字节数

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多