Блокировка кода при отправке данных через Socket - PullRequest
0 голосов
/ 31 марта 2020

В настоящее время я пытаюсь отправить изображение с моего Raspberry Pi на мой p c и отправить что-то обратно на PI с помощью библиотеки Socket. Отправка изображения работает, если я что-то не отправляю. Однако, если я попытаюсь отправить ответ на PI, оба кода, кажется, застряли. Может ли кто-нибудь помочь мне с этим?

Это мой код сервера:

import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('192.168.137.1', 5005))
server_socket.listen(5)
import os
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"                # om tekst van tensorflow import niet te laten zien
import tensorflow as tf
import cv2
import matplotlib.pyplot as plt
import numpy as np

model = tf.keras.models.load_model("C:/Users/antho/Bachelorproef/Models/(BLOK1&2&3)3-conv-128-nodes-2-dense-1585522274")

print("model loaded")

IMG_SIZE = 100

while (1):
    client_socket, address = server_socket.accept()
    print("Connected to - ",address,"\n")
    fp = open("C:/Users/antho/Bachelorproef/Socket_Tests/test.jpeg",'wb')
    while True:
        strng = client_socket.recv(512)
        if not strng:
            break
        fp.write(strng)
    fp.close()

    print("Image received")
    img = cv2.imread("C:/Users/antho/Bachelorproef/Socket_Tests/test.jpeg", cv2.IMREAD_GRAYSCALE)
    img = cv2.resize(img, (IMG_SIZE , IMG_SIZE))
    img = np.array(img).reshape(-1, IMG_SIZE, IMG_SIZE, 1)
    prediction = model.predict(img)
    print(np.argmax(prediction))

    pred = str(np.argmax(prediction))
    client_socket.sendall(bytes(pred, "utf-8"))
    print("send pred")

А это мой код клиента:

#!/usr/bin/python
# TCP client example
import socket,os
import io
import time
import picamera

# Create an in-memory stream
my_stream = io.BytesIO()
with picamera.PiCamera() as camera:
    camera.start_preview()
    # Camera warm-up time
    time.sleep(0.2)
    camera.capture(my_stream, format='jpeg')

my_stream.seek(0)                       # stream terug op begin zetten

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('192.168.137.1', 5005))
size = 1024

while(1):
    strng = my_stream.readline(512)
    # print(strng)
    if not strng:
        break
    client_socket.send(strng)

my_stream.close()

msg = client_socket.recv(512)
print(msg.decode("utf-8"))
print("Data Sent successfully")

Если я закомментирую финал Строки из этого кода, изображение отправляется в каталог с моего компьютера. С этим он застревает.

1 Ответ

0 голосов
/ 01 апреля 2020

Клиент отправляет данные изображения на сервер, но не предпринимает никаких действий, чтобы уведомить сервер о том, что все данные изображения были отправлены. Поскольку сервер не знает, что полный образ был получен, он все еще ждет в client_socket.recv получения дополнительных данных. Это означает, что сервер никогда не достигает вызова client_socket.sendall, и это означает, что клиент будет ждать в its client_socket.recv данные, которые никогда не поступят, потому что они никогда не отправлялись.

Это работает, вроде , когда вы удаляете client_socket.recv и последующие строки из клиента, потому что это позволяет клиентскому процессу достичь конца программы и выйти. Когда клиент выходит, его client_socket закрывается, и это разрывает соединение с сервером. Отключение соединения приводит к тому, что сервер client_socket.recv возвращается без данных, что вырывает сервер из while True l oop и позволяет продолжить работу, чтобы сохранить данные, полученные ранее, а затем обработать файл изображения.

Чтобы исправить, в клиентском вызове:

client_socket.shutdown(socket.SHUT_WR)

после того, как все данные изображения были отправлены. Это может go перед break внутри while(1) l oop или рядом с my_stream.close, это не имеет значения.

Это скажет серверу, что больше никаких данных не будет поступающий от клиента, но он все еще позволит сокету переносить данные в направлении сервер-клиент. Это позволит клиенту собрать ответ сервера pred.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...