双向udp通讯在python中不起作用

时间:2018-08-15 14:02:26

标签: python multithreading sockets udp

我想在服务器和客户端之间进行双向通信。我最终遇到了一个问题。

  1. 我正在从服务器获取主机ip,然后连接到它。但是我不确定如何将其从一个定义转换为另一个定义。

  2. 如果我直接指定主机IP,它将起作用。但是我不想要那样。 请发表您的想法。

客户端程序:

import socket
import os
import re
class cont():
    def get_bd(self):
        def receive_bd(self):
            # receive broadcast
            def get_ip_data(ether_adapter):

                ip_data = os.popen("ifconfig " + ether_adapter)
                for line in ip_data:
                    match2 = re.search(r'broadcast\s+(\d+.\d+.\d+.\d+)', line)
                    if match2:
                        bd = match2.group(1)
                        return bd

            if __name__ == "__main__":
                ethernet_card = "wlp1s0"
                inet_list = get_ip_data(ethernet_card)
                # print(inet_list)
            self.sock.bind((inet_list, 12345))
            msg, client = self.sock.recvfrom(1024)
            a = (msg.decode())
            #here i receive the ip of my server to the client
            host = a

    def send_ls(self):
        #i want the host i received in that receive_bd as a host here
        host= "here?if i give direct ip of server it works which i dont want to do but directly get it from receive_bd "
        port=4343
        address=host,port
        client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
        while (True):
            msg=input("Controller 1 :")
            client.sendto(bytearray(msg,"utf-8"),address)
            reply=client.recvfrom(1000)
            recved=str(reply)
            print("Main Controller: %s " %(recved))

if __name__=='__main__':
    c=cont()
    c.send_ls()

1 个答案:

答案 0 :(得分:0)

在我看来,您只需要启用发送到广播地址的功能即可。这是通过client.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)完成的。

我如下所示更改了您的send_ls,并且能够与侦听端口4343的UDP回显程序进行通信。这里的192.168.40.255是子网广播地址。

    def send_ls(self):
        host = '192.168.40.255'
        port=4343
        address=host,port
        client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
        client.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        while (True):
            msg=input("Controller 1 :")
            client.sendto(bytearray(msg,"utf-8"),address)
            reply=client.recvfrom(1000)
            recved=str(reply)
            print("Main Controller: %s " %(recved))

样品输出如下所示。请注意,服务器端未在bind中指定地址。因此,服务器能够接收发送到广播地址的消息,但是当它发回时,响应来自服务器网络适配器的单播地址。

Controller 1 :Hello there
Main Controller: (b'Hello there', ('192.168.40.128', 4343))
Controller 1 :You still there?
Main Controller: (b'You still there?', ('192.168.40.128', 4343))
Controller 1 :

另外一点:如果您的客户代码在这里记住从回复中获得的地址,那么它发送的后续消息就不需要去广播了地址。也就是说,只需在reply[1]之后将address分配给recvfrom,然后您就不会在第一条消息之后发送广播(这对于您的网络性能更好)。 / p>