2016-02-14 5 views
2

Я хочу создать сеть P2P. Это упрощенная программа, которая объясняет мою проблему.Может ли сокет одновременно слушать и подключать

Я хочу спросить, есть ли способ подключения и приема соединения одновременно.

Если нет, то сети P2P используют два порта, один для приема и другие для подключения.

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

Программа ниже дает мне следующую ошибку:

socket.error: [Errno 106] Transport endpoint is already connected

import socket 
from threading import Thread 

s = socket.socket() 
s.bind(('localhost', 6000)) 

def rec(): 
    s.listen(1) 
    c, addr = s.accept() 
    print 'Connection received from ' , addr 

def test(): 
    host = raw_input("Enter Host address : ") 
    port = input("Enter port : ") 
    s.connect((host, port)) 
    print s.getsockname()[0] 

def main(): 
    t = Thread(target=rec, args=()) 
    t.start() 
    test() 

if __name__ == '__main__': 
    main() 

ответ

1

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

Поскольку созданный сокет двунаправлен, приложение P2P может связываться в обоих направлениях и выбирать, кто выполняет соединение, и кто выполняет прослушивание, основываясь на других факторах. Например, вы можете использовать обе машины P2P, чтобы обе стороны могли начать разговор, но после его запуска он работает на двунаправленной трубке.

zeromq - интересная система обмена сообщениями, которая может использоваться для протоколов P2P. Он имеет очень подробное описание различных моделей связи и заслуживает внимания.

+0

Что вы подразумеваете под одной двунаправленной трубой? Не могли бы вы рассказать. –

+1

Предположим, у вас есть две машины h1 и h2. После того, как соединение было сделано, h1 'send' попадает в h2's recv и vica-versa. Неважно, кто начал разговор. Предположим, что у вас есть функция 'def my_p2p_conversation (connected_socket): ...', которая реализует ваш протокол с помощью отправки и получения. Он имеет гнездо для прослушивания, и если он получает запрос на соединение, он запускает приложение ('my_p2p_connection (listen_socket.accept())). Если пользователь хочет инициировать соединение, он выполняет 'my_p2p_connection (connection_socket.connect (('h2', 9876))). – tdelaney