我正在编写一个基于UDP的流媒体服务器,遇到了一个奇怪的问题,我确信这只是一个简单的错误,但我找不到解决方案。服务器执行以下操作:
FILE* infile = fopen(inf, "rb");
register int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
int16_t buffer[LENGTH+HEADER];
struct header header;
int16_t data[LENGTH];
uint32_t number = 0;
/*set socket options etc. */
while(!feof(infile)){
fread(data, 1, LENGTH, infile);
/* if i write the contents of data to a file here, the error below occurs*/
fwrite(data, 1, LENGTH, testfile);
/*create a header, encode everything with htons/htonl*/
if(sendto(sock, buffer, LENGTH+HEADER, 0, (struct sockaddr*) &to,
sizeof to) < 0)
/*die*/
}
这似乎奏效了。我可以解码,数据没有损坏。然而,我写了一个测试客户端,它的工作(或者更确切地说:不工作)如下:
struct sockaddr_in si_other, si_me;
register int s;
unsigned int slen = sizeof(si_other);
int16_t buf[LENGTH+HEADER];
int16_t data[LENGTH];
FILE* file = fopen(of, "wb");
/*open socket, set options, etc. */
while(1){
if(recvfrom(s, (char *)buf, LENGTH+HEADER, 0, (struct sockaddr*) &si_other,
&slen) < 0)
/*die*/
decode(buf, data);
/* If I write the decoded data to a file here, the error below occurs */
fwrite(data, 1, LENGTH, testfile);
if(is_empty(data) == 0){
printf("End signal received.n");
break;
}
}
现在来谈谈我的问题。当我用diff <(xxd test_before) <(xxd test_after)
检查十六进制的测试文件时,我得到了以下内容(例如diff行):
< 03d5ff0: f3fd f3fd 99fe 99fe 40ff 40ff e7ff e7ff ........@.@.....
---
> 03d5ff0: f3fd f3fd 0000 0000 0000 0000 0000 0000 ................
这意味着数据包数据的最后12个字节丢失。其他一切都很好。
这只是测试代码,所以它没有那么重要(我想),但它很奇怪,我想知道为什么。
有什么想法吗?
编辑:
我现在已经从答案中尝试了几种方法,但迄今为止没有取得任何进展。我会继续努力。
编辑2:
代码在另一台机器上工作。我不确定问题出在哪里,但除了我之外,它似乎对任何人都有效。很抱歉占用了你的时间,感谢你对如何改进代码等提出的友好建议!
提前感谢,Carson
您正在将2字节buf强制转换为char,并读取其中包含的一半。
recvfrom(s, (char *)buf, LENGTH+HEADER, 0, (struct sockaddr*) &si_other,
&slen)
buf数组有(LENGTH+HEADER) * 2
字节,您可以读取其中一半的
对于发送和接收,都使用char数组。
编辑
这是读取文件的方式:
unsigned char data[LENGTH];
fseek(inf, 0, SEEK_END);
int file_Size = ftell(inf);
fseek(inf, 0, SEEK_SET);
if(file_Size > LENGTH){
//file larger than data
}
fread(data, sizeof(unsigned char), file_Size, inf);
您的代码非常不完整,因此很难确定。数据是如何放入发送方的int16_t buffer[LENGTH+HEADER]
中的?解码和编码功能是什么样子的?
我可以看到的一个明显的危险是,缓冲区的类型是uint16_t
,即两个字节。函数sendto()
和recvfrom()
期望以字节为单位的缓冲区长度。换句话说,buf是实际告诉sendto()
的长度(以字节为单位)的两倍。因此,您的编码功能可能会使一些数据从发送/接收的pov中消失。
粗略猜测,丢失的12个字节可能是一个合适的4字节值或htonl()
处理后在发送中丢失的其他数据。
发布一个更完整的代码,以便更好地猜测。
如Edit 2中所述,该代码适用于我测试代码的所有机器,但我的除外。我不确定问题出在哪里,但除了我之外,它似乎对任何人都有效。很抱歉占用了你的时间,感谢你对如何改进代码等提出的友好建议!