简体   繁体   中英

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

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

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. Where am I going wrong? PS:I am currently using only one system and so only one local IP for all sockets.

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

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. 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. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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