简体   繁体   English

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

[英]connect two socket client connected by different threads as client server pair via a central server

I want to send a file from one connected client to other(both connected to a central server and running in different threads) such that the client sending becomes a server and other becomes the client. 我想将文件从一个连接的客户端发送到另一个客户端(两者都连接到中央服务器并在不同的线程中运行),以使客户端发送成为服务器,其他客户端成为客户端。 My code from main object is: lin=link() self.c.send(str('true').encode()) print("sent conf") lin.create_server(new.ip_address,path) the create_server function is 我的主要对象代码是: 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()

and for creating client is: 创建客户端的方法是:

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()

and the main server part that I am using to contact the client socket is 而我用来联系客户端套接字的主服务器部分是

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

and after some code: k.send(str(addr[0]+' '+filename).encode()) print("sent to k") 然后输入一些代码: k.send(str(addr[0]+' '+filename).encode()) print("sent to k")

The server is created and file to be sent is opened and the main server is also sending the ip to k(the last snippet) but the connection that is supposed to be client is not recieving it. 创建服务器并打开要发送的文件,并且主服务器也将ip发送到k(最后一个代码段),但是应该是客户端的连接未收到它。 Where am I going wrong? 我要去哪里错了? PS:I am currently using only one system and so only one local IP for all sockets. PS:我目前仅使用一个系统,因此所有套接字仅使用一个本地IP。

You've messed up your sockets. 您搞砸了您的套接字。

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

sock is a socket only used to listen for incoming connections. sock是仅用于侦听传入连接的套接字。 You cannot read or write to this socket. 您不能读写此套接字。

This while loop is for files larger than 4096 bytes, but each time through, you are waiting for a DIFFERENT connection, so the first chunk is processed for the first connection, the next chunk for the second connection and so on. 此while循环用于大于4096字节的文件,但是每次循环都在等待DIFFERENT连接,因此将为第一个连接处理第一个块,为第二个连接处理下一个块,依此类推。

while True:

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

    sock.send(chunk)

Again, you can't send to a listening socket! 同样,您不能发送到监听套接字! Perhaps you wanted conn.send(chunk) . 也许您想要conn.send(chunk)

What you really wanted was a loop more like: 您真正想要的是一个类似于以下的循环:

conn, addr = sock.accept()
while True:
    chunk = file.read(4096)
    if not chunk:
        break
    conn.send(chunk)
conn.close()

Unfortunately, the above won't work, because the socket buffer will quickly become full, and stop accepting data no matter how fast the program writes to it. 不幸的是,以上方法不起作用,因为套接字缓冲区将很快变满,并且无论程序写入它的速度如何,都将停止接受数据。

You need to check the return value from conn.send(chunk) to find out how many bytes were sent. 您需要检查conn.send(chunk)的返回值,以了解发送了多少字节。 If that is less than the length of the chunk , you need to remove that many bytes from the start of the chunk, and try to send the remainder. 如果该长度小于chunk的长度,则需要从块的开头删除那么多字节,然后尝试发送剩余的字节。 Repeat until the whole chunk is sent. 重复直到发送完整个块。

Or ... simply use conn.sendall(chunk) , which blocks until all the data has been accepted into the socket buffer. 或者...只需使用conn.sendall(chunk) ,它将阻塞直到所有数据都被接受到套接字缓冲区中为止。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM