C:在第一次连接时发送/接收部分数据包,并在第二次连接时接收其余数据包

时间:2014-10-19 19:41:39

标签: c network-programming

客户端代码

/* 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 再次丢失。

非常感谢任何帮助或建议!

3 个答案:

答案 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)

你有两个问题:

  1. 您的服务器代码在第二个printf的末尾没有换行符,因此输出不能是您显示的内容。将换行符附加到第二个printf,或在其后使用fflush(stdout),以刷新y的值。

  2. 正如Greg所说,你无论如何都不能依赖接收整个消息,而且应该有一个循环。

  3. 我希望#1成为您当前的问题,但您应该解决这两个问题。