TCP服务器无法接收全部数据

时间:2018-11-11 12:46:06

标签: python sockets tcp

我使用Python和TCP连接使服务器读取客户端发送的图像。然后服务器获取它的颜色代码,然后将颜色代码发送回客户端。

除了服务器没有收到完整的文件(我的情况是图片)之外,其他所有东西都工作正常。

我想我无法使循环正常工作,因为如果我将server.py脚本代码(请参见下面的代码)从img = connectionSocket.recv(2048)更改为img = connectionSocket.recv(200000),则服务器会收到整个图像

我想使其正常工作,以便服务器接收整个图像,而无需更改recv()函数中的缓冲区大小

这是client.py和server.py的脚本

Client.py

from socket import *
from PIL import Image

IP = '127.0.0.1'
PORT = 5000

#cSocket - created client socket
#img - sent image to the server
#ccode - colour code of the colour in the image
cSocket = socket(AF_INET, SOCK_STREAM)
cSocket.connect((IP,PORT))

with open ('Image.bmp','rb') as im:
    img = im.read()
cSocket.sendall(img)
print('Sent the image to the server..')
cCode=cSocket.recv(2048)

print('The colour code of the sent image is: ' + cCode.decode())
cSocket.close()

Server.py

from socket import *
from PIL import Image
import io
import PIL
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
IP = '127.0.0.1'
PORT = 5000

#sSocket - created server socket
#img - image received from the client
#cCode - colour code of the image
sSocket = socket(AF_INET, SOCK_STREAM)
sSocket.bind((IP,PORT))
sSocket.listen(1)

print ('The server is ready')

while 1:
    connectionSocket, addr = sSocket.accept()
    img = connectionSocket.recv(2048)
    if not img:
        break
    print (str(img))
    t_img = io.BytesIO(img)
    img = Image.open(t_img)
    cCode = img.getcolors(256)
    cCode = str(cCode)
    print (cCode)
    connectionSocket.send(cCode.encode())
    connectionSocket.close()

1 个答案:

答案 0 :(得分:0)

TCP是字节流协议。它没有消息边界的概念,因此您必须建立一个协议来确定是否有完整的消息。由于您发送一个数据Blob(一个.BMP图像),并接收一个数据Blob(颜色响应),因此一个简单的协议是:

  1. 将.BMP流式传输到套接字。
  2. 关闭写入套接字以向服务器指示映像已完成。
  3. 服务器发送响应。
  4. 服务器关闭套接字,指示响应已完成。

这是一个实现...

client.py

import socket
from PIL import Image

IP = '127.0.0.1'
PORT = 5000

with socket.socket() as cSocket:
    cSocket.connect((IP,PORT))

    with open('Image.bmp','rb') as im:
        img = im.read()
    cSocket.sendall(img)
    cSocket.shutdown(socket.SHUT_WR) # Indicate all data is sent

    print('Sent the image to the server..')

    # Collect data until socket closes.
    # Any size can be used in recv() with this protocol.
    cCode = b''
    while True:
        data = cSocket.recv(2048)
        if not data: break
        cCode += data

    print('The color code of the sent image is: ' + cCode.decode())

server.py

import socket
from PIL import Image
import io

IP = '127.0.0.1'
PORT = 5000

with socket.socket() as sSocket:
    sSocket.bind((IP,PORT))
    sSocket.listen(1)
    print ('The server is ready')
    while True:
        connectionSocket, addr = sSocket.accept()
        with connectionSocket:

            # Collect data until the client shuts down writing.
            # This protocol works with any size in recv()
            img = b''
            while True:
                data = connectionSocket.recv(2048)
                if not data:
                    break
                img += data
            t_img = io.BytesIO(img)
            img = Image.open(t_img)
            cCode = img.getcolors(256)
            cCode = str(cCode)
            print (cCode)
            connectionSocket.sendall(cCode.encode())