2015-10-06 21 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