Ошибка операционной системы: [ошибка 57] сокет не подключен

#python #json #sockets

#python #json #сокеты

Вопрос:

Я пытаюсь разобраться в работе сетей на Python с помощью socket модуля, но я думаю, проблема в том, что я действительно не понимаю, как на самом деле функционирует сервер или клиент.

Что я пытаюсь сделать:

  • Отправьте словарь с клиента на сервер, сначала превратив его в строку с помощью JSON
  • Заставьте сервер отправить клиенту сообщение, подтверждающее, что они подключены

Серверная программа

 import socket
import json

HOST = '192.168.X.X'
PORT = 50034


with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    s.listen(1)
    conn, addr = s.accept()

    with conn:
        while True:
            data = conn.recv(1024)
            new_data = data.decode()
            new_data = json.loads(data)
            print(new_data["Name"],"has connected from",addr)
            message = ("Hello %s welcome to the chat server" % new_data["Name"]).encode()
            s.sendall(message)
            if not data:
                conn.sendall(data)
  

Клиентская программа

 import socket
import json

HOST = '192.168.X.X'
PORT = 50034

my_dict = {"Name":"Bob"}
jsn = json.dumps(my_dict)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST,PORT))
    s.sendall((jsn).encode())
    data = s.recv(1024)
    print(data)
  

Но я получаю сообщение об ошибке:

Ошибка операционной системы: [ошибка 57] сокет не подключен

Почему?

Комментарии:

1. Вы пытаетесь отправить сообщение через прослушивающий сокет.

2. Что такое прослушивающий сокет? Это код внутри with conn: ?

3. s это прослушивающий сокет, тот, который вы вызывали listen() и принимаете от него, и s.send(...) это то место, откуда вы пытаетесь отправить сообщение, и где вы получаете эту ошибку.

4. Итак, как бы мне отправить данные за пределы прослушивающего сокета?

5. Так же, как вы это читаете?

Ответ №1:

Вам необходимо изменить код вашего сервера…

 s.sendall(message)
  

… кому …

 conn.sendall(message)
  

Это потому, что когда вы делаете …

 conn, addr = s.accept()
  

conn является новым экземпляром сокета для этого соединения. Итак, это объект, который вы должны использовать для отправки и получения данных по этому соединению. Перед вызовом accept() для подтверждения подключения у вас нет сокета, который на самом деле к чему-либо подключен.

Комментарии:

1. Или после. Прослушивающий сокет никогда не подключен.

2. @user207421 Я уточнил формулировку.