udp sendto无法实时发送整个txt文件

时间:2014-05-28 15:44:14

标签: c sockets udp

我真的很奇怪。我使用单播套接字进行服务器和客户端通信。 服务器以512字节的块发送文本文件,客户端正在接收和写入块到txt文件。但是我注意到没有睡眠(1)双方服务器上的功能都无法发送整个文件。例如,文件由2939个块组成,在wireshark中,我只能看到1827,2005,1657,但从来没有整个文件,所有2939个块?为什么?数据包不会丢失,因为服务器和客户端通过以太网电缆连接到路由器并且位于同一本地网络上。

您能告诉我如何解决这个问题的方向和建议吗?这是代码:

#includes...
#define BUF_SIZE 512
#define PORT 1234
#define IP "192.168.0.103" // address of a client

static int val = 1;
int sent=0;

int main() {

    struct sockaddr_in client,server;
    char tmp[BUF_SIZE];
    int n,s,fd;
    ssize_t numRead;
    int rv,optval=1;

    if((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))<0){
        printf("Opening datagram socket error",strerror(errno));
        return 1;

    }else{
        printf("Opening datagram socket....OK.\n");
    }

    if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1){ 
        printf("Setsockopt error: %s", strerror(errno));
        return 1;
    }


    memset((char *) &server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY; 
    server.sin_port = htons(PORT);

    memset((char *) &client, 0, sizeof(client));
    client.sin_family = AF_INET;
    client.sin_addr.s_addr = inet_addr(IP); 
    client.sin_port = htons(PORT);

    if(bind(s, (struct sockaddr*)&server, sizeof(server))){
        printf("Binding datagram socket error %s",strerror(errno));
        close(s);
        return 1;

    }


   if((fd = open("udp_text.txt", O_RDONLY , 0777))== -1){
      printf("Error while opening txt file %s!\n",strerror(errno));
      return 1;

   }

    while (1) {
        if((numRead = read(fd,tmp,512)) == 512){ 
            tmp[numRead]='\0';
            rv = sendto(s,tmp,sizeof(tmp),0, (struct sockaddr *) &client, sizeof(struct sockaddr_in));

        memset(tmp,0,BUF_SIZE);

        }else{
        rv = sendto(s,tmp,sizeof(tmp),0, (struct sockaddr *) &client, sizeof(struct sockaddr_in));
        printf("EOF !\n");
        return 1;
    }
}

close(s);
return 0;
}

THX

2 个答案:

答案 0 :(得分:0)

由于并非所有数据包都显示在wireshark中,我猜测发送方在操作系统中的网络数据包缓冲区空间不足。 UDP不仅会因传输故障而丢失数据包,而且如果任何路由组件的容量耗尽,并且因为太忙而被迫丢弃数据包。这包括本地互联网协议栈。

首先,检查sendto()中的错误代码。如果要责怪本地操作系统,则可能会有礼貌地报告错误。

更新:sendto()没有错误,那么,没有简单的解决方法。

最后一点注意事项/建议。即使主机之间的直接以太网连接也不能保证数据包始终能够通过。如果您依赖于可靠传输的文件数据,那么您需要从接收器添加某种确认响应以确认数据的成功接收。发送方中的关联逻辑可根据需要重新传输数据。

这是一项相当多的工作,为什么你可能宁愿切换到为你做这一切的TCP套接字。

答案 1 :(得分:0)

如果要通过UDP发送文件,至少要使用为此目的设计的现有协议,例如Trivial FTP(请参阅RFC 1350)。它提供缓冲区大小控制和丢弃数据包的安全性。