我相信 TCP 是可靠的。如果write(socket, buf, buf_len)andclose(socket) 返回没有错误,接收者将收到buf与长度完全相同的数据buf_len。
但是这篇文章说TCP不可靠。
A:
Run Code Online (Sandbox Code Playgroud)sock = socket(AF_INET, SOCK_STREAM, 0); connect(sock, &remote, sizeof(remote)); write(sock, buffer, 1000000); // returns 1000000 close(sock);乙:
Run Code Online (Sandbox Code Playgroud)int sock = socket(AF_INET, SOCK_STREAM, 0); bind(sock, &local, sizeof(local)); listen(sock, 128); int client=accept(sock, &local, locallen); write(client, "220 Welcome\r\n", 13); int bytesRead=0, res; for(;;) { res = read(client, buffer, 4096); if(res < 0) { perror("read"); exit(1); } if(!res) break; bytesRead += res; } printf("%d\n", bytesRead);测验问题 - 程序 B 完成后会打印什么?
Run Code Online (Sandbox Code Playgroud)A) 1000000 B) something less than 1000000 C) it will exit reporting an error D) could be any of the above遗憾的是,正确答案是“D”。但这怎么会发生呢?程序 A 报告所有数据都已正确发送!
如果这篇文章属实,我必须改变主意。但我不确定这篇文章是否属实。
这篇文章是真的吗?
TCP/IP 是可靠的,因为“可靠”一词具有非常特殊(且有限)的含义。
具体来说,当 write() 返回 1000000 时,它向您做出以下承诺:
但也有一些 write() 没有(并且通常不能)提供的保证。尤其:
请注意,在上面列出的所有情况下,问题都是在 write() 返回后发生的,这就是为什么 write() 在发生这些情况时不能只返回错误代码。(当然,稍后调用 write() 很可能会返回错误代码,但这并不能特别帮助您了解已交付字节和未交付字节之间的线位于何处)
TLDR:TCP/IP 比 UDP 更可靠,但不能 100% 铁定保证不会出错。如果您确实想确保您的字节在接收端得到处理,您需要对接收应用程序进行编程,以发回某种更高级别的确认,表明它已收到(并成功处理!)您发送的字节。