TCP客户端无法将字符串发送到服务器

时间:2014-02-12 06:13:44

标签: c linux tcp send

我正在编写TCP服务器客户端。我使用单独的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

感谢。

2 个答案:

答案 0 :(得分:3)

尝试打印read_size。您可能已收到所有消息。

由于Nagle's Algorithm,发件人可能会批量处理您的三个send()来电并向服务器发送一个数据包。虽然您可以禁用Nagle的算法,但在这种情况下我认为这不是一个好主意。您的服务器需要能够处理部分数据的接收,并处理接收的数据超出预期。

您可能希望考虑为邮件使用上层协议,例如Google Protocol Buffers。看看techniques页面,它们描述了它们如何做到这一点:构建协议缓冲区,并在写入缓冲区之前将其长度写入流。这样,接收方可以读取长度,然后确定在有完整消息之前需要读取多少字节。

答案 1 :(得分:3)

TCP不是消息协议,而是字节流协议。

三个send - s可以recv - 作为单个输入(或其他内容,例如两个或五个recv等等。)

应用程序应该分析输入并缓冲它以便能够将它拼接在有意义的消息中。

传输可以拆分或合并消息,例如中间路由器可以并将分割或合并“数据包”。

在实践中,你最好对你的消息有一些很好的约定。要么决定每条消息是例如换行符终止,或者确定它以某个标题开头给出它的大小。

查看HTTPSMTPIMAPSCGIONC/XDR(在RFC5531中记录)作为具体示例。并且很好地记录了您的协议​​(最小化,对于一些家庭作业玩具项目的长描述性评论,更严重的是,在单独的公共文档中)。