TCP-сервер не получает целые данные - PullRequest
0 голосов
/ 11 ноября 2018

Я использовал Python и TCP-соединение для создания сервера, который читает изображение, отправленное клиентом.Затем сервер получает код цвета и отправляет код цвета клиенту.

Все работает нормально, за исключением того, что сервер не получает полный файл (изображение в моем случае).

Полагаю, я не могу заставить цикл работать, потому что сервер действительно получает все изображение, если я изменю код сценария server.py (см. Код ниже) с img = connectionSocket.recv(2048) на img = connectionSocket.recv(200000)

Я хочу, чтобы это работало, чтобы сервер получал все изображение без изменения размера буфера в recv() function

Вот сценарии 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 голосов
/ 11 ноября 2018

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())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...