TCP / IP传输期间套接字数据损坏

时间:2010-11-23 19:00:52

标签: c sockets

当我通过预先连接的TCP-IP套接字发送数据时,我发现数据已损坏。

实施例

Station1正在向Station2发送数据。我在发送(S1)和接收(S2)之前打印了数据。以下是信息:

S1: 发送的数据为ACK
S2: 收到的数据为AC�����

不确定是什么问题。我甚至在发送数据之前(在S1)和接收之前(在S2)清除了char缓冲区。

上述任何提示/信息都会有很大帮助。

3 个答案:

答案 0 :(得分:4)

这通常是以下结果:

/* BAD CODE */
const char* ack = "ACK";
err = write( sockfd, ack, strlen( ack )); /* sender */
/* ... */
char buf[SOME_SIZE]
readb = read( sockfd, buf, SOME_SIZE ); /* receiver */
printf( "%s", buf );

上面代码的问题是发送方只向套接字写入三(3)个字节。这不包括字符串零终结符。然后接收器获取数据并且根本不检查系统调用返回值或/并盲目地打印接收的数据。 printf将打印所有内容,直到它在内存中找到零值字节。

编辑:

基于你的评论,我认为你假设一个send(2)通过TCP套接字应该在另一端产生一个recv(2)并且具有相应的字节数(我猜这就是你的意思通过“读取错误的字节数”)。但这不是TCP的情况。您必须将套接字视为一个流,它可以为您提供任意大小的块。将它们重新组合在一起并识别应用程序消息边界是您的职责。这只是意味着你总是从循环中的套接字读取(不包括select(2)和朋友的非阻塞设计 - 这是一个单独的主题。)

两种可接受的应用程序级协议设计是:

  • 通过预定义的固定长度消息进行通信 - 这样您就可以阅读,直到从套接字中获取了那么多字节。简单。
  • 将消息类型和/或消息长度包含在消息本身中 - 这通常使用固定长度的消息头来完成,后面跟着不同的消息有效负载。阅读,直到你得到完整的标题,然后根据类型/长度切换/发送/继续阅读。

不要忘记endianess - network byte order等网络。

答案 1 :(得分:2)

您确定立刻收到了整条信息吗?由于TCP是基于流的协议,因此您在Station2上读取的数据可以分成小块数据。你必须查看recv()函数放入缓冲区的数据量。

例如,您对recv()的第一次调用可能会出现“AC” 然后,下一个电话可能会给你剩下的数据“K”

答案 2 :(得分:0)

在客户端,我将一个字符串发送到套接字:

char message[200];

/*string to be sent*/
strcpy(message, "Hi PQRS, How are you!?");

/*send string to server's socket*/
if( send(socket_desc , message , strlen(message)+1 , 0) < 0)
    {
        puts("Send failed");
        return 1;
    }
puts("Data Sent\n");

注意我如何传递

  

'strlen(消息)+ 1'

允许分隔符,即'\ 0' 而不是

  

'strlen的(消息)'

它确保字符串的结尾,并且不会添加额外的数据。

无论服务器端的字符数组大小如何,只要它等于或大于传入的字符串以便容纳它,它都可以工作。