我编程TCP服务器的客户端。 我送三串seperately使用单独的send
系统调用。 但是,接收端我只得到一个字符串,它是我送的第一个字符串。 剩下的两个字符串错过。
下面我给出我的服务器客户端程序的一部分。
client.c
char *info = "infolog";
char *size = "filesize";
char *end = "fileend";
send(client, info, strlen(info)+1, 0);
send(client, size, strlen(size)+1, 0);
send(client, end, strlen(end)+1, 0);
server.c
while ((read_size = recv(client, msg, sizeof(msg), 0))) {
printf("Data: %s\n", msg);
memset(msg, 0, sizeof(msg));
}
实际输出:
Data: infolog
预计输出
Data: infolog
Data: filesize
Data: fileend
谢谢。
尝试打印出来read_size
。 你可能已经收到的所有邮件。
由于Nagle算法 ,发件人可能分批起来你的三个send()
调用和发送一个数据包到服务器。 虽然你可以禁用Nagle算法,我不认为这是在这种情况下,一个好主意。 你的服务器需要能够处理接收部分数据,并处理接收的数据量超出预计。
您可能要考虑使用的上层协议为您的信息,如谷歌协议缓冲器 。 看看的技术页面,在那里他们描述他们如何做到这一点:建立一个协议缓冲区,写缓冲区本身之前写它的长度到流。 在接收端通过这种方式可以读取的长度,然后决定需要多少字节读取它有一个完整的消息之前。
TCP是不是一个消息的协议,但字节流的协议。
这三个send
-s可以recv
-ed作为一个单一的输入(在两个或五个或别的东西,比如recv
等...)
应用程序应该分析输入和缓冲它能够拼接它有意义的信息。
传输可以拆分或合并的消息,例如中间路由器可以并且将拆分或合并的“包”。
在实践中,你会更好地对您的邮件一些好的约定。 或者决定每个消息是例如换行终止,或者决定它与一些头给予其尺寸开始。
看HTTP , SMTP , IMAP , SCGI或ONC / XDR (中记录RFC5531 )作为具体例子。 并记录相当不错的协议(一极小,在一些功课玩具项目较长的描述性注释,更严重的是,一个单独的公开文件)。