[英]Socket Programming; File corrupts when transferring over multiple devices
The problem I'm having is to get a file from the server to client across devices. 我遇到的问题是跨设备从服务器到客户端获取文件。 Everything works fine on localhost. 在localhost上一切正常。 Lets say I want to "get ./testing.pdf" which sends the pdf from the server to the client. 假设我要“获取./testing.pdf”,它将pdf从服务器发送到客户端。 It sends but it is always missing bytes. 它发送但始终丢失字节。 Is there any problems with how I am sending the data. 我如何发送数据有任何问题。 If so how can I fix it? 如果可以,我该如何解决? I left out the code for my other functionalities since they are not used for this function. 我没有为其他功能添加代码,因为这些功能未用于此功能。
sending a txt file with "hello" in it works perfectly 发送带有“ hello”的txt文件非常有效
server.py server.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()
client.py client.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
I can see two problems right away. 我马上就能看到两个问题。 I don't know if these are the problems you are having, but they are problems. 我不知道这些是否是您遇到的问题,但它们是问题。 Both of them relate to the fact that TCP is a byte stream, not a packet stream. 两者都与TCP是字节流而不是包流这一事实有关。 That is, recv
calls do not necessarily match one-for-one with the send
calls. 也就是说, recv
呼叫不一定与send
呼叫一对一匹配。
size = s.recv(1024)
It is possible that this recv
could return only some of the size digits. size = s.recv(1024)
此recv
可能仅返回某些大小数字。 It is also possible that this recv
could return all of the size digits plus some of the data. 此recv
还可能返回所有大小数字以及一些数据。 I'll leave it for you to fix this case. 我将它留给您解决此问题。
data += s.recv(bufsize)
/ size -= bufsize
There is no guarantee that that the recv
call returns bufsize
bytes. data += s.recv(bufsize)
/ size -= bufsize
不能保证recv
调用返回bufsize
字节。 It may return a buffer much smaller than bufsize. 它可能返回比bufsize小得多的缓冲区。 The fix for this case is simple: datum = s.recv(bufsize)
/ size -= len(datum)
/ data += datum
. 这种情况的解决方法很简单: datum = s.recv(bufsize)
/ datum = s.recv(bufsize)
size -= len(datum)
/ data += datum
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.