Python:不写最后字节tcp



你好,我写了一个简单的程序来传输文件,但是我有一个问题:程序不发送给我一个完整的文件,并且在while条件下停止。

服务器来源:

#simple transfer files server
import socket, sys
SRV_ADDR = ""
SRV_PORT = 9900
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((SRV_ADDR, SRV_PORT))
s.listen(1)
connection, address = s.accept()
while 1:
    pippo = connection.recv(1024)   
    if(pippo.decode('utf-8') == '3'):
       riceivename=connection.recv(1024)
       lettore=riceivename.decode('utf-8')
       file = open(lettore, 'rb') 
       while 1:
           data = file.read(1024)
           if not data: break
           connection.sendall(data)
       file.close()
       print("ok end cicle")   
           
           
    elif(data.decode('utf-8') == '0'):
          connection.close()
          connection, address = s.accept()
客户:

import sys
import socket
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect(('127.0.0.1', 9900))
def print_menu():
    print("""nn0) Close the connection
3) Receive file""")
print("Connection established")
print_menu()
while 1:
    message = input("n-Select an option: ")
    if (message=="3"):
        sock.sendall(message.encode())
        localname=input("name with which you want to save the file:")
        file = open(localname, 'wb') 
        path=input("insert remote path of file to be downloaded:")
        sock.sendall(path.encode())
        while 1:
           data=sock.recv(1024)
           if not data:break
           file.write(data)
        file.close()
    elif(message=="0"):
         sock.sendall(message.encode())
         sock.close()
         break
    print_menu()

我认为客户端没有写最后一个字节。我不明白是什么问题

问题是您的客户端被阻塞在data=sock.recv(1024)。由于服务器没有关闭连接,服务器仍然可以发送更多的数据,因此客户端需要等待。您可以通过发送一个文件来检查这一点,当客户端在recv()处被阻塞时,终止服务器进程。客户端的recv()将返回'',然后关闭文件。源文件和目标文件比较应该相等。

正确的解决方案是在所有数据发送到客户端后关闭服务器中的套接字。您还需要将accept()移动到循环中,以便可以从新的客户端连接处理进一步的请求。这是修改后的服务器:

#simple transfer files server
import socket, sys
SRV_ADDR = ""
SRV_PORT = 9900
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((SRV_ADDR, SRV_PORT))
s.listen(1)
while 1:
    connection, address = s.accept()
    pippo = connection.recv(1024)
    if(pippo.decode('utf-8') == '3'):
       riceivename=connection.recv(1024)
       lettore=riceivename.decode('utf-8')
       file = open(lettore, 'rb')
       while 1:
           data = file.read(1024)
           if not data: break
           connection.sendall(data)
       connection.close()
       file.close()
       print("ok end cicle")
    elif(data.decode('utf-8') == '0'):
          connection.close()

这是修改后的客户端:

import sys
import socket
def print_menu():
    print("""nn0) Close the connection
3) Receive file""")
while 1:
    print_menu()
    message = input("n-Select an option: ")
    if (message=="3"):
        sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        sock.connect(('127.0.0.1', 9900))
        print("Connection established")
        sock.sendall(message.encode())
        localname=input("name with which you want to save the file:")
        file = open(localname, 'wb')
        path=input("insert remote path of file to be downloaded:")
        sock.sendall(path.encode())
        while 1:
           data=sock.recv(1024)
           if not data:break
           file.write(data)
        file.close()
        sock.close()
    elif(message=="0"):
         sock.sendall(message.encode())
         sock.close()
         break

客户端为每次文件传输建立一个新的连接。"0"选项不再有用,但我在代码中保留了它。

如果您不希望每次都建立新的连接,那么您将需要有一些方法来指示客户端文件传输已经完成。当连接用于数据传输和命令时,这将很难做到。关闭套接字是解决这个问题最简单的方法。

最新更新