为什么假定发送可能比一个阻塞套接字发送请求的数据用更少的回报? [英] Why is it assumed that send may return with less than requested data transmitted on a blocking socket?

查看:163
本文介绍了为什么假定发送可能比一个阻塞套接字发送请求的数据用更少的回报?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要派一个流套接字数据的标准方法一直呼吁用数据来写,检查返回值看一大块发送,如果所有的数据被发送,然后不断的打电话再次发送,直到整个消息已接受了。

The standard method to send data on a stream socket has always been to call send with a chunk of data to write, check the return value to see if all data was sent and then keep calling send again until the whole message has been accepted.

例如,这是一个共同计划的一个简单的例子:

For example this is a simple example of a common scheme:


int send_all(int sock, unsigned char *buffer, int len) {
  int nsent;

  while(len > 0) {
    nsent = send(sock, buffer, len, 0);
    if(nsent == -1) // error
      return -1;

    buffer += nsent;
    len -= nsent;
  }
  return 0; // ok, all data sent
}

即使是BSD手册页提到,

Even the BSD manpage mentions that

...如果没有消息可用空间,在插座持有该邮件被发送,然后发送()通常块 ...

...If no messages space is available at the socket to hold the message to be transmitted, then send() normally blocks...

这表明,我们应该假定发送可能不发送的所有数据恢复。现在我发现这个相当打破,但即使是理查德·史蒂文斯假定这个约网络编程他的标准参考书,不在开始的章节,但更高级的示例用自己writen(写入所有数据)函数而不是调用写的。

Which indicates that we should assume that send may return without sending all data. Now I find this rather broken but even W. Richard Stevens assumes this in his standard reference book about network programming, not in the beginning chapters, but the more advanced examples uses his own writen (write all data) function instead of calling write.

现在我认为这仍然是或多或少坏了,如果送不,因为能够在基础缓冲区传输所有数据或接受数据和插座被挡住,然后发送应该阻止,并返回整个发送请求时已被接受。

Now I consider this still to be more or less broken, since if send is not able to transmit all data or accept the data in the underlying buffer and the socket is blocking, then send should block and return when the whole send request has been accepted.

我的意思是,在上述code例如,如果与发送更少的数据发送的回报会发生什么事是,这将是一个新的请求权再次调用。自最后一次通话发生了什么变化?在最高几百个CPU周期已经过去了,因此缓冲区仍然是满的。如果发送现在接受的数据,为什么could'nt之前接受吗?

I mean, in the code example above, what will happen if send returns with less data sent is that it will be called right again with a new request. What has changed since last call? At max a few hundred CPU cycles have passed so the buffer is still full. If send now accepts the data why could'nt it accept it before?

否则,我们将结束与UPP效率低下的循环,我们正试图发送一个无法接受的数据和不断尝试,否则套接字上的数据?

Otherwise we will end upp with an inefficient loop where we are trying to send data on a socket that cannot accept data and keep trying, or else?

因此​​,它似乎是解决办法,如果需要的话,会导致大量低效code和在这些情况下阻止套接字应在所有的非阻塞插座与选择一起可以避免应该使用。

So it seems like the workaround, if needed, results in heavily inefficient code and in those circumstances blocking sockets should be avoided at all an non blocking sockets together with select should be used instead.

推荐答案

这是上面的描述中缺少的东西是,在Unix中,系统调用可能会得到与信号中断。这正是阻塞原因的发送(2)可能会返回一个短的计数。

The thing that is missing in above description is, in Unix, system calls might get interrupted with signals. That's exactly the reason blocking send(2) might return a short count.

这篇关于为什么假定发送可能比一个阻塞套接字发送请求的数据用更少的回报?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆