繁体   English   中英

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

[英]Socket data corrupted during TCP/IP transfer

当我通过预先连接的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的(消息)'

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM