当我通过预连接的 TCP-IP 套接字发送数据时,我发现数据已损坏。
示例:
Station1 正在向 Station2 发送数据。我已经在发送前(在 S1)和接收后(在 S2)打印了数据。以下是消息:
S1:
发送的数据是ACK
S2:
收到的数据是 AC������
不确定是什么问题。我什至在发送数据(在 S1 处)和接收数据(在 S2 处)之前清除了字符缓冲区。
上述任何提示/信息都会有很大帮助。
最佳答案
这通常是以下情况的结果:
/* 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 并非如此。您必须将套接字视为一个流,它可以为您提供任意大小的数据 block 。将它们放回一起并识别应用程序消息边界是您的工作。这只是意味着您总是在循环中从套接字读取(不包括使用 select(2)
和 friend 的非阻塞设计 - 这是一个单独的主题)。
两个公认的应用程序级协议(protocol)设计是:
- 通过预定义的固定长度消息进行通信 - 以这种方式读取,直到从套接字中获得那么多字节。简单。
- 在消息本身中包含消息类型和/或消息长度 - 这通常通过固定长度的消息 header 完成,后跟不同的消息负载。阅读直到获得完整标题,然后根据类型/长度切换/发送/继续阅读。
不要忘记 endianess - 类似network byte order 的网络.
关于c - 套接字数据在 TCP/IP 传输期间损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4259722/