2016-01-23 3 views
0

Мне просто не удается добавить многопоточность на мой UDP-сервер. Второй клиент может подключиться, но мгновенно выкидывается из сервера, когда кто-то уже подключен к нему.Python: 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 

ответ

0

Вы не можете написать прокси UDP с единственным портом. Как вы должны знать из ответа сервера, на какой из двух подключенных клиентов вы должны отправить свой ответ. Вы должны открыть для каждого клиента новый сокет на удаленном сервере.

+0

Мне очень жаль, но я новичок в Python. Не могли бы вы привести мне пример, как это сделать? – juggernawt

0

Это не Python, а «сеть» и, конечно же, не «многопоточность». Вам нужно либо направлять клиентов на разные порты, либо создавать новый исходящий сокет для каждого нового клиентского соединения.

Поскольку у вас есть несколько сокетов, очень эффективный подход - сидеть на 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]) 
Смежные вопросы