Python:UDP代理多线程

时间:2016-01-23 18:37:27

标签: python multithreading udp

我无法管理将多线程添加到我的UDP服务器。 第二个客户端可以连接,但当有人连接到服务器时,它会立即被抛出服务器。

这可能是由SingleThreading以外的东西引起的吗?

import sys, socket
localPort, remoteHost, remotePort = sys.argv[1].split(':')
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('', localPort))
except:
    fail('Failed to bind on port ' + str(localPort))

knownClient = None
knownServer = (remoteHost, remotePort)
sys.stderr.write('Ready.\n')


while True:
    data, addr = s.recvfrom(32768)
    print addr
    if knownClient is None:
        knownClient = addr
    if addr == knownClient:
        try:
            s.sendto(data, knownServer)
        except:
            pass
    else:
        try:
            s.sendto(data, knownClient)
        except:
            pass

2 个答案:

答案 0 :(得分:0)

您不能只使用端口编写UDP代理。您应该如何从服务器的答案中知道您应该向您发送答案的两个连接客户端中的哪一个。您必须为每个客户端打开一个到远程服务器的新套接字。

答案 1 :(得分:0)

它不是Python而是#34;网络"而且肯定不是"多线程"。您需要将客户端定向到不同的端口,或者为每个新的客户端连接创建一个新的传出套接字。

因为您有多个套接字,所以非常有效的方法是坐在select上并等待来电。

为了识别客户端,还需要保留新套接字用于与服务器通信的本地地址的引用。

您的代码经过重新设计,可以在每个新传入的客户端连接上打开socket。没有保证,因为这将涉及对未知的情景(你的)进行网络测试。

对于非常强大的实现,您必须添加错误检查,删除连接的套接字...

import select
import socket
import sys


localPort, remoteHost, remotePort = sys.argv[1].split(':')

try:
    server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    server.bind(('', localPort))
except:
    fail('Failed to bind on port ' + str(localPort))

localaddr = s.getsockname()  # (localhost, localport)
remaddr = (remoteHost, remotePort)

sys.stderr.write('Ready.\n')

allsockets = [server]

proxysocks = dict()
origins = dict()


while True:
    toread, _, _ = select.select(allsockets, [], [])

    s = toread[0]  # 1st socket available to read
    data, orig = s.recvfrom(32768)  # data, (remhost,remport)
    dest = s.getsockname()  # (localhost, localport)

    if dst == localaddr:  # client -> localserver
        try:
            p = proxysocks[orig]  # find proxy sock
        except KeyError:  # new client connection
            proxysocks[orig] = p = socket.socket(socket.AF_INET,
                                                 socket.SOCK_DGRAM)

            proxyaddr = p.getsockname()  # keep local address of new socket
            origins[proxyaddr] = orig  # link proxyaddr -> clientaddr

            allsockets.append(p)  # make it "selectable"

        p.sendto(remaddr, data)  # send to server

    else:  # server -> proxyaddr
        s.sendto(origins[dstaddr])