通过中央服务器

时间:2018-05-10 21:07:22

标签: python python-3.x sockets networking

我想从一个连接的客户端向其他客户端发送文件(都连接到中央服务器并在不同的线程中运行),以便客户端发送成为服务器而其他客户端成为客户端。我的主要对象代码是:                        lin=link() self.c.send(str('true').encode()) print("sent conf") lin.create_server(new.ip_address,path) create_server函数是

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]+' '+filename).encode()) print("sent to k")

创建服务器并打开要发送的文件,主服务器也将ip发送到k(最后一个片段),但应该是客户端的连接没有收到它。我哪里错了? P.S:我目前只使用一个系统,因此所有套接字只有一个本地IP。

1 个答案:

答案 0 :(得分:0)

你搞砸了你的插座。

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((ip, 12345))
sock.listen(1)

sock是一个仅用于侦听传入连接的套接字。您无法读取或写入此套接字。

此while循环适用于大于4096字节的文件,但每次都要等待一个不同的连接,因此第一个连接处理第一个连接,第二个连接处理下一个块,依此类推。 / p>

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)的返回值,以了解发送了多少字节。如果它小于chunk的长度,则需要从块的开头删除那么多字节,并尝试发送余数。重复,直到发送整个块。

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