在Python中通过TCP套接字发送文件

时间:2014-12-02 04:19:30

标签: python file sockets python-2.7 tcp

我已成功将文件内容(图像)复制到新文件中。但是,当我在TCP套接字上尝试相同的事情时,我面临着问题。服务器循环未退出。客户端循环在到达EOF时退出,但服务器无法识别EOF。

以下是代码:

服务器

import socket               # Import socket module

s = socket.socket()         # Create a socket object
host = socket.gethostname() # Get local machine name
port = 12345                 # Reserve a port for your service.
s.bind((host, port))        # Bind to the port
f = open('torecv.png','wb')
s.listen(5)                 # Now wait for client connection.
while True:
    c, addr = s.accept()     # Establish connection with client.
    print 'Got connection from', addr
    print "Receiving..."
    l = c.recv(1024)
    while (l):
        print "Receiving..."
        f.write(l)
        l = c.recv(1024)
    f.close()
    print "Done Receiving"
    c.send('Thank you for connecting')
    c.close()                # Close the connection

客户端

import socket               # Import socket module

s = socket.socket()         # Create a socket object
host = socket.gethostname() # Get local machine name
port = 12345                 # Reserve a port for your service.

s.connect((host, port))
s.send("Hello server!")
f = open('tosend.png','rb')
print 'Sending...'
l = f.read(1024)
while (l):
    print 'Sending...'
    s.send(l)
    l = f.read(1024)
f.close()
print "Done Sending"
print s.recv(1024)
s.close                     # Close the socket when done

这是截图:

服务器 Server

客户端 Client

编辑1:复制的额外数据。使文件"不完整。" 第一列显示已收到的图像。它似乎比发送的更大。因此,我无法打开图像。它似乎是一个损坏的文件。

File sizes

编辑2:这是我在控制台中的操作方式。这里的文件大小相同。 Python Console Same file sizes

5 个答案:

答案 0 :(得分:27)

客户端需要使用socket.shutdown(不是socket.close关闭套接字的读/写部分)来通知它已完成发送:

...
print "Done Sending"
s.shutdown(socket.SHUT_WR)
print s.recv(1024)
s.close()

<强>更新

客户端将Hello server!发送到服务器;写入服务器端的文件。

s.send("Hello server!")

删除上面的行以避免它。

答案 1 :(得分:6)

删除以下代码

s.send("Hello server!")

因为您向服务器发送s.send("Hello server!"),所以您的输出文件的大小更大。

答案 2 :(得分:1)

问题是server.py在开始时收到的额外13个字节。要解决这个写&#34; l = c.recv(1024)&#34;在while循环之前两次,如下所示。

print "Receiving..."
l = c.recv(1024) #this receives 13 bytes which is corrupting the data
l = c.recv(1024) # Now actual data starts receiving
while (l):

这解决了问题,尝试使用不同格式和大小的文件。如果有人知道这个起始13个字节指的是什么,请回复。

答案 3 :(得分:0)

将文件放在while True内,如此

while True:
     f = open('torecv.png','wb')
     c, addr = s.accept()     # Establish connection with client.
     print 'Got connection from', addr
     print "Receiving..."
     l = c.recv(1024)
     while (l):
         print "Receiving..."
         f.write(l)
         l = c.recv(1024)
     f.close()
     print "Done Receiving"
     c.send('Thank you for connecting')
     c.close()   

答案 4 :(得分:0)

您可以发送一些标志以在服务器中循环时停止

例如

服务器:

import socket
s = socket.socket()
s.bind(("localhost", 5000))
s.listen(1)
c,a = s.accept()
filetodown = open("img.png", "wb")
while True:
   print("Receiving....")
   data = c.recv(1024)
   if data == b"DONE":
           print("Done Receiving.")
           break
   filetodown.write(data)
filetodown.close()
c.send("Thank you for connecting.")
c.shutdown(2)
c.close()
s.close()
#Done :)

clinet:

import socket
s = socket.socket()
s.connect(("localhost", 5000))
filetosend = open("img.png", "rb")
data = filetosend.read(1024)
while data:
    print("Sending...")
    s.send(data)
    data = filetosend.read(1024)
filetosend.close()
s.send(b"DONE")
print("Done Sending.")
print(s.recv(1024))
s.shutdown(2)
s.close()
#Done :)