【发布时间】:2022-06-10 17:38:31
【问题描述】:
我正在开发一个实现 TCP 客户端-服务器的 C 项目。我使用的套接字和send() 函数是在库sys/socket.h 和winsock2.h 中定义的。
我的问题是,当我尝试一个接一个地发送多个字符串时,一些消息没有正确传输,一些数据(有时是所有消息)丢失了。例如,当我在同一台机器上运行服务器和客户端时,以下代码可以正常工作,但如果我尝试使用远程服务器运行它,则无法正确接收第三条消息。
客户端
char message[1024];
memset(message, 0, 1024);
fill_message(message, msg1); //A function that prints something in the message string.
//It may fill less than 1024 characters.
send(clientSocket, message, 1024,0);
fill_message(message, msg2);
send(clientSocket, message, 1024,0);
fill_message(message, msg3);
send(clientSocket, message, 1024,0);
服务器端
char message[1024];
memset(message, 0, 1024);
recv(clientSocket, message, 1024,0);
print_and_do_stuff(message);
recv(clientSocket, message, 1024,0);
print_and_do_stuff(message);
recv(clientSocket, message, 1024,0);
print_and_do_stuff(message);
注意:字符串 message 的长度可能不完全是 1024。
我的解决方案是在发送每条消息后通过调用sleep(1) 让客户端等待 1 秒。这是解决问题的正确方法吗?还是我错过了 send() 和 recv() 的工作原理?
更笼统地说:用套接字编程的“正确”方法是什么?我是否应该逐字节发送消息并将长度指定为第一件事?如果有人可以为我提供有关使用套接字时的最佳实践的良好教程/指南,我很乐意阅读。
【问题讨论】:
-
'如果有人可以向我指出一个很好的教程/指南,说明使用套接字时的最佳实践是什么'哦,这很容易 - 所以'套接字'选项卡,特别是。常见问题解答。你知道 - 关于 TCP 字节流的问答,正确和完整地处理来自系统调用(如 send/recv)的返回,以及正确使用需要以 NUL 终止的字符数组作为参数的 C 库调用。
-
@MartinJames 我不确定我是否正确理解您的评论:在我发现的发送/接收 documentation 中,它没有指定参数需要以 nul 终止。另外,this 是您所说的常见问题解答吗?在“socket”标签下搜索 TCP 字节流只会显示这个
-
简而言之:您假设
send与recv完全匹配。这种假设对于 TCP 来说是错误的,因为 TCP 只是没有固有消息边界的字节流。使用 C、Python 或其他任何东西都没有关系。 -
@SteffenUllrich 好的,当我告诉发件人在再次开始发送之前“等待”时,程序可以正常工作,这只是因为接收者有时间正确接收和停止
recv执行?