2015-10-06 22 views
1

我遇到的问题是跨设备从服务器获取文件到客户端。一切工作正常localhost。 假设我想要“get ./testing.pdf”,它将pdf从服务器发送到客户端。它发送但它总是丢失字节。我是如何发送数据的。如果是这样,我该如何解决它?我遗漏了我的其他功能的代码,因为它们不用于此功能。套接字编程;通过多个设备传输时文件损坏

发送一个txt文件,用 “你好” 它完美

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

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 

回答

2

我可以看到两个问题的时候了。我不知道这些是你遇到的问题,但它们是问题。它们都涉及TCP是字节流而不是数据包流这一事实。也就是说,recv呼叫不一定与send呼叫一对一匹配。

  1. size = s.recv(1024)这是可能的,这recv只能返回一些的尺寸数字。也有可能这recv可能会返回所有的大小数字加上的一些数据。我会留给你解决这个问题。

  2. data += s.recv(bufsize)/size -= bufsize没有保证的recv调用返回bufsize字节。它可能会返回比bufsize小得多的缓冲区。这种情况下的修复很简单:datum = s.recv(bufsize)/size -= len(datum)/data += datum