我想从一个连接的客户端向其他客户端发送文件(都连接到中央服务器并在不同的线程中运行),以便客户端发送成为服务器而其他客户端成为客户端。我的主要对象代码是:
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。
答案 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)
,它会阻塞,直到所有数据都被接受到套接字缓冲区中。