在简单的python程序中,我丢失了udp数据包

时间:2015-08-07 10:09:43

标签: python sockets udp

操作系统:Windows 8

IDE 用于python工具链的Eclise Juno + Aptana插件

语言 Python 3.3

我尝试将两个udp数据包从一台计算机发送到另一台计算机。 这是源代码

from socket import *
import time

port=5000
ip_addr='192.168.4.122'
my_ip='192.168.4.6'

sock = socket(AF_INET,SOCK_DGRAM)
sock.bind((my_ip,port))

data=bytes([0xc9,0x01,0,0,0xc8,port & 0x00ff,(port >> 8) & 0x00ff,0,1,1,0,1,0,ord('F'),ord('P')])
sock.sendto(data,(ip_addr,port))
data=bytes([0xc9,0x01,0,0,0xc8,port & 0x00ff,(port >> 8) & 0x00ff,0,1,1,0,1,0,ord('k'),ord('f'),ord('?')])
sock.sendto(data,(ip_addr,port))

time.sleep(3)

print("end of the programm");

但如果我运行wireshark(在两台计算机中),我只看到第一个数据包。哪里丢了第二包???我做错了什么???在我的交换机只连接两台计算机。我添加了sendto调用结果的输出。这些结果是可能的。

5 个答案:

答案 0 :(得分:2)

尝试使用socket.send而不是socket.sendto。 除此之外,UDP是一个"发送并忘记"协议。如果您想确定数据是否到达,则需要使用TCP。

答案 1 :(得分:2)

@Ayy如果我在" sendto"之间添加time.sleep(1)然后所有数据包都已成功发送。

答案 2 :(得分:0)

特别为@ayy我继续调查。我用C语言编写这个程序。

   int main(void) {
        struct sockaddr_in udp_addr;
        struct sockaddr_in remote_addr;
        int on=1;
        int snd_rcv_buf = 131072;
        int sock_fd;
        socklen_t udp_addr_len;

        char data[] = { 0xc9,0x01,0,0,0xc8,0x88,0x13,0,1,1,0,1,0,0x46,0x50 };
        char data1[] = { 0xc9,0x01,0,0,0xc8,0x88,0x13,0,1,1,0,1,0,0x6b,0x66,0x3f };

        sock_fd = socket(PF_INET, SOCK_DGRAM, 0);

        setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
        setsockopt(sock_fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
        setsockopt(sock_fd, SOL_SOCKET, SO_RCVBUF, &snd_rcv_buf, sizeof(snd_rcv_buf));
        setsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, &snd_rcv_buf, sizeof(snd_rcv_buf));

        memset(&udp_addr, 0, sizeof(udp_addr));
        udp_addr.sin_family = AF_INET;
        udp_addr.sin_port = htons(5000);
        udp_addr_len = sizeof(udp_addr);

        if (inet_aton("192.168.4.66", &udp_addr.sin_addr) == 0)
        {
            printf( (char *)"Address translate error\n");
            return -1;
        }

        if (bind(sock_fd, (struct sockaddr*)&udp_addr, udp_addr_len)!=0)
        {
            printf((char *)"Error bind udp-socket\n");
            return -1;
        }

        memset(&remote_addr, 0, sizeof(remote_addr));
        remote_addr.sin_family = AF_INET;
        if (inet_aton("192.168.4.122", &remote_addr.sin_addr)==0)
            printf((char *)"remote address translate error");
        remote_addr.sin_port = htons(5000);


        int res = sendto(sock_fd, data, /*len*/15, 0, (struct sockaddr*)&remote_addr, udp_addr_len);
        printf("%d ",res);
        res = sendto(sock_fd, data1, /*len*/16, 0, (struct sockaddr*)&remote_addr, udp_addr_len);
        printf("%d ",res);

        puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */
        return EXIT_SUCCESS;
}

情况已经重演。但是.................. Atention !!!!!!!如果我在RedHat 6.5虚拟机中调用此代码(主机是Windows 8),则所有数据包都已成功发送。 Wauuuuuu。一切正常。事实证明,操作系统Windows 8中存在问题???????????

答案 3 :(得分:0)

我在本地尝试了你的代码

[root @ localhost#] #tcpdump -i lo src 127.1.1.1 tcpdump:详细输出被抑制,使用-v或-vv进行完整协议解码 监听lo,链接型EN10MB(以太网),捕获大小65535字节 19:32:10.905035 IP 127.1.1.1.commplex-main> 127.1.1.1.commplex-main:UDP,长度54 19:32:10.905069 IP 127.1.1.1.commplex-main> 127.1.1.1.commplex-main:UDP,长度60

答案 4 :(得分:0)

@HSEM请参阅此代码摘录。

int res = sendto(sock_fd, data, /*len*/15, 0, (struct sockaddr*)&remote_addr, udp_addr_len);
printf("%d ",res);
res = sendto(sock_fd, data1, /*len*/16, 0, (struct sockaddr*)&remote_addr, udp_addr_len);
printf("%d ",res);

如果我评论printf那么。

   int res = sendto(sock_fd, data, /*len*/15, 0, (struct sockaddr*)&remote_addr, udp_addr_len);
//    printf("%d ",res);
    res = sendto(sock_fd, data1, /*len*/16, 0, (struct sockaddr*)&remote_addr, udp_addr_len);
//    printf("%d ",res);

我开始丢失数据包。事实证明,“sendto”调用之间的延迟问题。如果它存在比完全工作。如果没有延迟,那么我开始丢失数据包。类似的情况在python代码https://stackoverflow.com/a/31889368/1936079中。