简体   繁体   English

C:UDP数据包的最后字节丢失

[英]C: Last Bytes of UDP packets lost

I am writing an UDP-based streaming server and encountered a strange problem, I am sure it's just a simple error, but I cannot find a solution. 我正在编写基于UDP的流服务器,遇到一个奇怪的问题,我敢肯定这只是一个简单的错误,但是我找不到解决方案。 The server does something along the lines of: 服务器执行以下操作:

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*/            
}

This seems to work. 这似乎有效。 I can decode it and the data is not corrupt. 我可以解码它,并且数据没有损坏。 However, I wrote a test client that works(or rather: does not work) as follows: 但是,我编写了一个测试客户端,它可以正常工作(或更确切地说:不工作),如下所示:

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;
    }
} 

Now to my problem. 现在到我的问题。 When I inspect the test files in hex with diff <(xxd test_before) <(xxd test_after) , I get this(example diff line): 当我用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  ................

Which means that the last 12 bytes of the packets' data are lost. 这意味着数据包数据的最后12个字节将丢失。 Everything else is fine. 其他一切都很好。

This is only test code, so it is not as important(I guess), but it is weird and I want to know why. 这只是测试代码,所以它并不那么重要(我想),但这很奇怪,我想知道为什么。

Any ideas? 有任何想法吗?

EDIT: 编辑:

I have now tried a few approaches from the answers, thus far without getting anywhere. 现在,我已经从答案中尝试了几种方法,但到目前为止没有任何进展。 I will keep trying. 我会继续努力。

EDIT 2: 编辑2:

The code works on a different machine. 该代码在另一台机器上工作。 I am not sure what the problem was, but it seems to work for anyone but me. 我不确定问题出在哪里,但它似乎对我以外的任何人都有效。 Sorry for stealing your time and thank you for all the kind suggestions on how to improve the code and such! 很抱歉浪费您的时间,并感谢您提供有关如何改进代码等的所有建议!

Thanks in advance, Carson 预先感谢,卡森

You are casting a 2 bytes buf to char and read half of it contains. 您正在将2个字节的 buf强制转换为char并读取其中的一半。

recvfrom(s, (char *)buf, LENGTH+HEADER, 0, (struct sockaddr*) &si_other,
             &slen) 

The buf array has (LENGTH+HEADER) * 2 bytes and you read half of it buf数组具有(LENGTH+HEADER) * 2个字节,您读取了一半

Use char arrays for both send and receive . char数组用于sendreceive

EDIT 编辑

This the way to read the file: 这种读取文件的方式:

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);

Your code is very incomplete, so it is difficult to say anything for certain. 您的代码非常不完整,因此很难说出什么。 How is the data put in int16_t buffer[LENGTH+HEADER] on the sending side? 数据如何放在发送方的int16_t buffer[LENGTH+HEADER] What do the decode and encode functions look like? 解码和编码功能是什么样的?

One obvious hazard I can see is that your buffers are of type uint16_t , which is two bytes. 我可以看到一个明显的危险是您的缓冲区的类型为uint16_t ,即两个字节。 The functions sendto() and recvfrom() expect the buffer length in bytes. 函数sendto()recvfrom()期望缓冲区长度以字节为单位。 In other words, your buf is double the length (in bytes) that you actually tell sendto() . 换句话说,buf是实际告诉sendto()的长度(以字节为单位)的两倍。 Thus your encoding function might make some data disappear, from the pov of the send/receive. 因此,您的编码功能可能会使一些数据从发送/接收的视点中消失。

Wild guess, 12 bytes missing might be a suitable 4 byte value or other data htonl() processed and then lost in send. 疯狂猜测,丢失12个字节可能是合适的4个字节的值或其他经过处理的htonl()数据,然后在发送中丢失。

Post a more complete code, for better guesses. 发布更完整的代码,以获得更好的猜测。

As noted in Edit 2, the code works on all machines I tested the code on but mine. 如编辑2所述,该代码可在所有我在其上测试过的代码的机器上运行,但我的代码是这样。 I am not sure what the problem was/is, but it seems to work for anyone but me. 我不确定问题出在哪里,但似乎对我以外的任何人都有效。 Sorry for stealing your time and thank you for all the kind suggestions on how to improve the code and such! 很抱歉浪费您的时间,并感谢您提供有关如何改进代码等的所有建议!

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

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