Python 通过中央服务器将两个由不同线程连接的套接字客户端作为客户端-服务器对连接

Python 通过中央服务器将两个由不同线程连接的套接字客户端作为客户端-服务器对连接,python,python-3.x,sockets,networking,Python,Python 3.x,Sockets,Networking,我想将一个文件从一个连接的客户端发送到另一个客户端(都连接到中央服务器并在不同的线程中运行),这样发送的客户端就变成了服务器,而另一个客户端就变成了客户端。我的主要对象代码是: lin=link() self.c.send(str('true').encode()) 打印(“已发送配置”) lin.create\u服务器(新的.ip\u地址、路径) 创建服务器功能是 def create_server(self,ip,path ): connection_list = [] #i

我想将一个文件从一个连接的客户端发送到另一个客户端(都连接到中央服务器并在不同的线程中运行),这样发送的客户端就变成了服务器,而另一个客户端就变成了客户端。我的主要对象代码是:
lin=link()
self.c.send(str('true').encode())
打印(“已发送配置”)
lin.create\u服务器(新的.ip\u地址、路径)
创建服务器功能是

def create_server(self,ip,path ):
    connection_list = []
    #ip='127.0.0.1'
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind((ip, 12345))
    print("server created")
    connection_list.append(sock)
    sock.listen(1)
    #offset = 0
    file = open(path, "rb")
    print("file opened")
    while True:
        conn, addr = sock.accept()
        connection_list.append(conn)
        read_sockets,write_sockets,error_sockets = select.select(connection_list,[],[])
        chunk = file.read(4096)
        print("chunk read")
        if not chunk:
            break  # EOF
        sock.send(chunk)
        print("chunk sent")
    print("Transfer complete")
    #sock.shutdown()
    sock.close()
用于创建客户端的是:

def create_client(self,ip,file ):
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    #ip='127.0.0.1'
    print(str(file))
    client.connect((ip, 12346 ))
    print("client created")
    with open(str(file), 'wb') as f:
      socket_list = [client]
      print("file opened")
      while True:
        read_sockets,write_sockets,error_sockets = select.select(socket_list,[],[])
        data=client.recv(4096)
        print("recieved data")
        if not data:
          break
      f.write(data)
      print("Transfer complete")
    f.close()
    time.sleep(5)
    #client.shutdown()
    client.close()
我用来联系客户机套接字的主要服务器部分是

for i in self.list_of_conns:#[conn,addr] appended every time a connection is made to main server
                    if i[1][0]==cli_ip:
                        k=i[0]  #the conn from conn,addr=server.accept() part
                        m=1
                        break
在一些代码之后:
k.send(str(addr[0]+''+文件名).encode())
打印(“发送到k”)

创建服务器并打开要发送的文件,主服务器也将ip发送到k(最后一个代码段),但假定为客户端的连接没有接收到它。我哪里做错了?
注意:我目前只使用一个系统,所以所有套接字都只有一个本地IP。

您的套接字都搞乱了

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((ip, 12345))
sock.listen(1)
sock
是仅用于侦听传入连接的套接字。无法读取或写入此套接字

此while循环用于大于4096字节的文件,但每次通过时,您都在等待不同的连接,因此第一个块将针对第一个连接进行处理,下一个块将针对第二个连接进行处理,依此类推

while True:

    conn, addr = sock.accept()
    chunk = file.read(4096)
    if not chunk:
        break  # EOF

    sock.send(chunk)
同样,您不能发送到侦听套接字!也许您想要
conn.send(chunk)

您真正想要的是一个更像:

conn, addr = sock.accept()
while True:
    chunk = file.read(4096)
    if not chunk:
        break
    conn.send(chunk)
conn.close()
不幸的是,上述方法不起作用,因为套接字缓冲区将很快变满,并停止接受数据,无论程序写入数据的速度有多快

您需要检查
conn.send(chunk)
的返回值,以确定发送了多少字节。如果该长度小于
块的长度
,则需要从块的开头删除那么多字节,然后尝试发送剩余的字节。重复此操作,直到发送整个数据块

或者。。。只需使用
conn.sendall(chunk)
,它会一直阻塞,直到所有数据都被接受到套接字缓冲区