2016-05-15 272 views
1

我试图通过套接字传输文件,如果我立即关闭连接立即关闭连接 现在我想继续发送命令到服务器上传完成后,但服务器只是忽略他们,并认为有更多的线路来对文件Python通过套接字传输文件

这里是我到目前为止的代码 客户:

def client_sender(): 
    global upload 
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

    try: 
     print target 
     print port 
     client.connect((target, port)) 

     if upload: 
      with open(upload_destination, "rb") as f: 
       for line in f: 
        client.send(line) 
      f.close() 
      client.send("DONE\r\n") 
      upload = False 

     print client.recv(1024) 
     buffer = "" 
     buffer = sys.stdin.read() 
#... some code for sending commands and receiving a response 

服务器:

def handle_client(client_socket): 
    global upload 
    print "Client connected" 
    if upload: 
     file_buffer = "" 
     while True: 
      data = client_socket.recv(1024) 
      if data.rstrip() == "DONE": 
       break 
      file_buffer += data 
     try: 
      file_descriptor = open(upload_destination, 'wb') 
      file_descriptor.write(file_buffer) 
      file_descriptor.close() 

      client_socket.send("Successfully placed the file in %s" %upload_destination) 
     except: 
      client_socket.send("Failed writing to the file") 

     upload = False 
#... same as client, just some more code for commands 
+1

如果文件包含“DONE”,会发生什么情况会很有趣。 – mhawke

+0

这是为了传输我编写的已编译的C程序,所以没有办法可以适得其反 – Aginu

回答

3

尝试打印data的值后data = client_socket.recv(1024) 您可能会看到类似于:"endofthefile\nDONE\r\n"

所以当你运行rstrip时,你会得到:"endofthefile\nDONE",这不等于"DONE"

你应该重写你的while循环是这样的:

while True: 
     data = client_socket.recv(1024) 
     for line in data.split('\n'): 
      if data.rstrip() == "DONE": 
       break 
      file_buffer += line + '\n' 

你也可以使用该客户端上的宣布结束:client.sendall("DONE\r\n")sendall立即刷新客户端的缓冲区,而不是等待更多的数据在同一个数据包中发送。


偏离主题,但我建议你改变你的协议。如果文件包含DONE行,它将不起作用;这样在服务器上分割线是不够的。 更好的方法是让客户端公布文件的大小,然后继续发送它,以便服务器知道何时停止阅读。

+0

我试过了你的代码示例,但它并不能真正解决问题 但是,你的建议是改变协议的声音很不错,所以我会试一试!非常感谢你! – Aginu