客户端代码:
/* Packet struct */
struct
{
int x;
int y;
char mess [5];
} Packet;
/* Assigning values to packet */
Packet.x = 5;
Packet.y = 25;
strcpy(Packet.mess, "Hell");
/* Send packet */
int bytesTransmitted = send(socketID, &Packet, sizeof(Packet), 0);
/* Check transmission */
if (bytesTransmitted < 0)
{
printf("Error sending message!\n");
return 1;
}
else
{
printf("Message sent successfully! Message size: %lu, bytes trasnmitted: %d", sizeof(message), bytesTransmitted);
}
/* End of pogram */
return 0;
服务器代码:
struct
{
int x;
int y;
char mess [5];
} Packet;
unsigned int clientLength = sizeof(clientAddress);
/* Main loop */
while (1)
{
int listenSocket = accept(socketID, (struct sockaddr*)&clientAddress, &clientLength);
if (listenSocket > 0) /* Connection accepted */
{
printf("Received connection from: %s:%d\n", inet_ntoa(clientAddress.sin_addr), ntohs(clientAddress.sin_port));
if (recv(listenSocket, &Packet, sizeof(Packet), 0) > 0)
{
printf("Message: %s\n x:%d\n y:%d", Packet.mess, Packet.x, Packet.y);
/* HERE IS THE PROBLEM */
}
}
}
第一次连接时服务器的输出:
Received connection from: 127.0.0.1:48648
Message: Hell
x:5
y 缺失。
我终止客户端并重新启动它而不触及服务器。
服务器输出:
y:25 <-- *y* from ?previous? connection
Received connection from: 127.0.0.1:49368
Message: Hell
x:5 <-- *x* from current connection
y 再次丢失。
非常感谢任何帮助或建议!
答案 0 :(得分:2)
TCP是面向流的协议。没有&#34;数据包&#34;在你正在编写代码的级别。 TCP保证您发送的相同字节将以相同的顺序到达目的地。但是,没有消息边界。
调用recv()
的代码必须准备好接收比请求的更少的字节,并再次调用recv()
,直到获得预期的字节数。
答案 1 :(得分:1)
你的问题与TCP流无关(虽然你确实遇到了这个问题,应该根据Greg的答案修复它)。
相反,您的问题是输出缓冲 - 默认情况下,stdout是行缓冲的,这意味着用printf
编写的字符实际上进入缓冲区并且仅在\n
时输出到屏幕(换行符写入缓冲区。所以你的行:
printf("Message: %s\n x:%d\n y:%d", ...
只打印到最后一个换行符(y之前),y:25
只会放入缓冲区。之后,当您打印包含换行符的更多内容时,缓冲的字符串将与您打印的其他内容一起显示。在“y:%d”之后添加换行符,它会在您预期时出现。
答案 2 :(得分:1)
你有两个问题:
您的服务器代码在第二个printf的末尾没有换行符,因此输出不能是您显示的内容。将换行符附加到第二个printf,或在其后使用fflush(stdout)
,以刷新y
的值。
正如Greg所说,你无论如何都不能依赖接收整个消息,而且应该有一个循环。
我希望#1成为您当前的问题,但您应该解决这两个问题。