简体   繁体   English

套接字编程; 在多个设备上传输时文件损坏

[英]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呼叫一对一匹配。

  1. 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. 我将它留给您解决此问题。

  2. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM