我遇到的问题是跨设备从服务器向客户端获取文件。本地主机上一切正常。 假设我想“get ./testing.pdf”,它将 pdf 从服务器发送到客户端。它发送但总是丢失字节。我发送数据的方式有问题吗?如果是这样我该如何修复它?我省略了其他功能的代码,因为它们不用于此功能。
发送一个包含“hello”的txt文件效果很好
服务器.py
import socket, os, subprocess # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
#host = ''
port = 5000 # Reserve a port for your service.
bufsize = 4096
s.bind((host, port)) # Bind to the port
s.listen(5) # Now wait for client connection.
while True:
c, addr = s.accept() # Establish connection with client.
print 'Got connection from', addr
while True:
userInput = c.recv(1024)
.... CODE ABOUT OTHER FUNCTIONALITY
elif userInput.split(" ")[0] == "get":
print "inputed get"
somefile = userInput.split(" ")[1]
size = os.stat(somefile).st_size
print size
c.send(str(size))
bytes = open(somefile).read()
c.send(bytes)
print c.recv(1024)
c.close()
客户端.py
import socket, os # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
#host = '192.168.0.18'
port = 5000 # Reserve a port for your service.
bufsize = 1
s.connect((host, port))
print s.recv(1024)
print "Welcome to the server :)"
while 1 < 2:
userInput = raw_input()
.... CODE ABOUT OTHER FUNCTIONALITY
elif userInput.split(" ")[0] == "get":
print "inputed get"
s.send(userInput)
fName = os.path.basename(userInput.split(" ")[1])
myfile = open(fName, 'w')
size = s.recv(1024)
size = int(size)
data = ""
while True:
data += s.recv(bufsize)
size -= bufsize
if size < 0: break
print 'writing file .... %d' % size
myfile = open('Testing.pdf', 'w')
myfile.write(data)
myfile.close()
s.send('success')
s.close
最佳答案
我立刻就发现了两个问题。我不知道这些是不是你所面临的问题,但它们确实是问题。它们都与 TCP 是字节流而不是数据包流这一事实有关。也就是说,recv
调用不一定与 send
调用一一匹配。
size = s.recv(1024)
此recv
可能仅返回某些 size 数字。此recv
也有可能返回所有大小数字加上一些数据。我会把这个问题留给你来解决。data += s.recv(bufsize)
/size -= bufsize
不保证recv
调用返回bufsize
字节。它可能返回一个比 bufsize 小得多的缓冲区。这种情况的修复很简单:datum = s.recv(bufsize)
/size -= len(datum)
/data += datum
.
关于python - 套接字编程;通过多个设备传输时文件损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32960008/