python:不写最后一个字节tcp?

时间:2014-07-04 10:24:20

标签: python sockets tcp

您好我写了一个简单的程序来传输文件,但我有一个问题:

程序不会向我发送完整的文件并在条件下停止。

这是来源:

服务器来源:

#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("""\n\n0) 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()

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

任何人都可以帮助我吗?先谢谢

1 个答案:

答案 0 :(得分:0)

问题是您的客户在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("""\n\n0) 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”选项不再有用,但我把它留在了代码中。

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