C 客户端发送500字节,但服务器接收244字节-套接字编程?
我正在尝试为C 客户端发送500字节,但服务器接收244字节-套接字编程?,c,sockets,C,Sockets,我正在尝试为UDP实现停止并等待ARQ。根据停止和等待约定,我在0和1之间切换我的ACK 正确的ACK被定义为正确的序列号(0或1)和正确的消息长度 以下代码片段是我的代码相关部分 客户端 通过这个实现,我得到了以下结果: 客户端结果 服务器端结果 可以看出,客户端发送长度为500的消息,因此希望ACK为0500。然而,服务器接收长度为244的消息,并发回ACK0 244。因为它们不匹配,所以当前的实现就到此为止 为什么会出现这种长度差异?在您的客户机中,您正在执行 sendto(sockfd,
UDP
实现停止并等待ARQ
。根据停止和等待约定,我在0
和1
之间切换我的ACK
正确的ACK
被定义为正确的序列号(0
或1
)和正确的消息长度
以下代码片段是我的代码相关部分
客户端
通过这个实现,我得到了以下结果:
客户端结果
服务器端结果
可以看出,客户端发送长度为500
的消息,因此希望ACK
为0500
。然而,服务器接收长度为244
的消息,并发回ACK
0 244
。因为它们不匹配,所以当前的实现就到此为止
为什么会出现这种长度差异?在您的客户机中,您正在执行
sendto(sockfd, &sends, strlen(sends), 0, addr, addrlen)
你想要的是
sendto(sockfd, &sends, slen, 0, addr, addrlen)
斯特伦的问题有两个原因:
(1) 不允许null终止缓冲区,更重要的是,
(2) 您正在发送的二进制数据可能有一个空字节作为其245字节
经验法则:永远不要对二进制数据使用字符串函数。您可能不应该使用
strlen
来确定两端数据的长度,因为这将阻止您发送任何二进制数据。此外,在服务器上,如果数据是文件的结尾,那么看起来您希望数据的结尾处只有0字节,因此在所有其他情况下,strlen
调用也会给出不可靠的结果。使用recvfrom
的返回值确定您收到的数据量
代码的另一个问题是:
buf = (char *) malloc(lsize);
...
buf[lsize] ='\0'; // append the end byte
您正在分配一个与文件大小相等的内存缓冲区,然后在该内存的末尾设置一个0字节,这将导致长期出现问题。您应该为此分配一个额外的字节,因此:
buf = (char *) malloc(lsize+1);
...
buf[lsize] ='\0'; // append the end byte
更新:
在查看完整代码后,我看到了真正的问题:
struct ack_so
{
uint8_t num; // the sequence number
uint8_t len; // the packet length
};
ack_so::len
是一个8位无符号整数,其值范围为0-255,因此500将溢出该值,得到244
您应该使
len
auint32\u t
和ack.len=strlen(recvs)相同代码>太奇怪了。你说的完全有道理。但在我修改后,问题仍然存在…这很有道理,但我不知道为什么在我修改后问题仍然存在。谢谢!我不确定您的发送的。说第二个参数应该是指针而不是变量,对吗?我仍然认为应该是&发送。哦,我明白了!有道理。但正如我所说,错误仍然存在。。。完整代码可在以下位置获得:、和。有了完整的代码,我想你可以在你的电脑上复制、粘贴、运行它。非常感谢你!我发布了我答案的更新。问题在于您的ack\u so
结构。len是一个8位无符号整数,其值不能大于255。
sendto(sockfd, &sends, slen, 0, addr, addrlen)
buf = (char *) malloc(lsize);
...
buf[lsize] ='\0'; // append the end byte
buf = (char *) malloc(lsize+1);
...
buf[lsize] ='\0'; // append the end byte
struct ack_so
{
uint8_t num; // the sequence number
uint8_t len; // the packet length
};