在标准的tcp实现中(比如说,在bsd上),是否有人知道是否可以找出远程主机已经确认了多少字节?在套接字上调用write()会返回写入的字节数,但我相信这实际上意味着可以放入tcp缓冲区的字节数(不是写入网络的字节数,或者是已确认的字节数)。或许我错了......
谢谢!
答案 0 :(得分:1)
当你有NODELAY = false(这是默认值)时,当你用比TCP窗口更少的字节调用send()时,字节实际上不是立即发送的,所以你是对的。操作系统会稍微等一下,看看你是否调用另一个send(),以便只使用一个数据包来传输组合数据,并避免浪费TCP头。
当NODELAY = true时,调用send()时会传输数据,因此您可以(理论上)依赖返回的值。但由于网络效率低下,不推荐这样做。
总而言之,如果您不需要绝对精度,即使NODELAY = true,也可以使用send()返回的值。该值不会反映直接的实际情况,但会在几毫秒之后(但也会检查丢失的连接,因为您发送的最后一个数据块可能已丢失)。一旦连接正常终止,您就可以信任所有传输的数据。如果不是,您之前就会知道 - 要么是因为连接突然断开,要么是因为您收到了与数据保留相关的错误(或任何其他错误)。
答案 1 :(得分:1)
我不知道有什么方法可以解决这个问题,无论如何它可能对你没什么用。
假设您想知道主机收到了多少数据,以便在连接丢失和重新连接后,您可以再次从那里开始发送。因此,ACK确认的数据仅由OS确认!它不表示您的程序在另一方收到了哪些数据;根据TCP接收缓冲区的大小,你的程序可能会落后数百KB。如果你想知道那里的程序接收了多少数据和'',那么就让它发送应用程序级别的ACK
答案 2 :(得分:0)
我认为你错了,虽然它是其中一个我想看看具体实施的地方,然后才打赌它会有很多钱。但是,请考虑TCP连接的情况,其中在原始握手之后立即删除连接。如果返回的字节数只是缓冲的数量,那么显然可以写入多个字节,但是它们仍然没有传送;这将违反TCP的交付保证财产。
但请注意,这只适用于TCP;并非IP中的所有协议都提供相同的保证。
答案 3 :(得分:0)
使用ioctl(fd, TIOCOUTQ, &intval);
将传出队列转换为intval
,您可能会对TCP有所帮助。这将是队列中保留的总长度,包括“由应用程序编写”但尚未发送。它仍然是我现在能想到的最佳近似值。