我正在编写一个玩具会议点/中继服务器,监听端口5555,为两个客户端"A"和"B"提供服务。
它的工作原理是:服务器从首先连接的客户端A接收到的每个字节都将被发送到第二个连接的客户端B,即使A和B不知道彼此的IP地址:
A -----------> server <----------- B # they both connect the server first
A --"hello"--> server # A sends a message to server
server --"hello"--> B # the server sends the message to B
这段代码目前可以正常工作:
# server.py
import socket, time
from threading import Thread
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.bind(('', 5555))
socket.listen(5)
buf = ''
i = 0
def handler(client, i):
global buf
print 'Hello!', client, i
if i == 0: # client A, who sends data to server
while True:
req = client.recv(1000)
buf = str(req).strip() # removes end of line
print 'Received from Client A: %s' % buf
elif i == 1: # client B, who receives data sent to server by client A
while True:
if buf != '':
client.send(buf)
buf = ''
time.sleep(0.1)
while True: # very simple concurrency: accept new clients and create a Thread for each one
client, address = socket.accept()
print "{} connected".format(address)
Thread(target=handler, args=(client, i)).start()
i += 1
您可以通过在服务器上启动它并对其进行两个netcat连接来测试它:nc <SERVER_IP> 5555
。
那么我该如何将信息传递给客户端A和B,使它们能够直接交流而不必经过服务器?
有两种情况:
一般情况,即使A和B不在同一个本地网络中
特定情况下,这两个客户端在同一个本地网络中(例如:使用相同的家用路由器),当这两个客户端通过端口5555连接到服务器时,服务器将显示这一点:
('203.0.113.0', 50340) connected # client A, router translated port to 50340
('203.0.113.0', 52750) connected # same public IP, client B, router translated port to 52750
注:此前的一次不成功尝试在此:UDP或TCP打洞以连接两个分别位于路由器后面的对等方和使用第三方进行UDP打洞