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

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

例:

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

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

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

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

这通常是以下结果:

 /* 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 – 网络字节顺序等网络 。

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

例如,你第一次调用recv()可以得到“AC”然后,下一个调用可能会给你剩下的数据“K”

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

 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的(消息)'

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

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