#python #sockets #python-3.8
#python #сокеты #python-3.8
Вопрос:
Я пытаюсь создать сервер чата между 2 машинами, но есть проблема с подключением. Хотя он изначально подключается, когда дело доходит до отправки каких-либо фактических данных, сокет отключается.
Серверный код
import socket
import sys
import time
messages = []
x= socket.socket()
h_name = socket.gethostname()
print('Server will start on host address:', h_name)
port = 8000
bind = False
while bind == False:
try:
x.bind((h_name, port))
bind = True
print('This server is running on port', port)
except(OSError): #if the port connection doesn't work
if port == 65535:
print('Please restart the machine and relaunch this program')
else:
port = port 1 #increment the port by 1 and try again
print('Trying Port ' str(port) '...')
print( "Server done binding to host and port successfully")
print("Server is waiting for incoming connections")
x.listen(1)
connection,address= x.accept()
print(address, "has connected to the server and is now online...")
while 1:
display_mess= input(str(">>"))
if display_mess == 'QUIT': #if the user wants to quit
confirmation = input('Are you sure you would like to quit (Y/N)? ')
confirmation = confirmation.upper()
if confirmation == 'Y':
print('Press enter to quit...')
input()
exit()
else:
display_mess=display_mess.encode()
connection.send(display_mess)
print("Message has been sent...")
in_message=connection.recv(1024)
in_message=in_message.decode()
print("Client:", in_message)
Приведенный выше код должен настроить сервер и ожидать подключения от клиента, а затем они должны иметь возможность обмениваться данными, хотя и по одному сообщению за раз. Сначала сервер должен отправить сообщение, а затем клиент.
Клиентский код
import socket
import sys
import time
global port
port = 8000
def getHostName():
global h_name
h_name= input(str("Enter the hostname of the server: "))
def portConnect(h_name,port):
x = socket.socket()
connected = False
while connected == False:
x = socket.socket()
try:
x.connect((h_name,port))
print("Connected to chat server")
connected = True
except(ConnectionRefusedError):
print('Port', port, 'is incorrect')
print('Trying port ' str(port 1) '...')
port = int(port 1)
portConnect(h_name,port)
def while1():
x = socket.socket()
while 1:
x = socket.socket()
try:
incoming_message=x.recv(1024)
incoming_message=incoming_message.decode()
print(" Server :", incoming_message)
message= input(str(">>"))
if message == 'QUIT':
confirmation = input('Are you sure you would like to quit (Y/N)? ')
confirmation = confirmation.upper()
if confirmation == 'Y':
print('Press enter to quit...')
input()
exit()
else:
message =message.encode()
x.send(message)
print(" message has been sent...")
else:
message =message.encode()
x.send(message)
print(" message has been sent...")
except(OSError):
print('Please check the server machine is running')
cont = input('Would you like to quit the program or continue (Q/C): ')
if cont.isnum() != True and len(cont) > 0:
cont = cont.upper()
if cont == 'C':
getHostName()
else:
print('Press enter to exit')
input()
exit()
getHostName()
portConnect(h_name, port)
while1()
Приведенный выше код должен создать клиентский компьютер и выполнить поиск сервера на заранее определенном порту и локальной сети и дождаться соединения с сервером, а затем они должны иметь возможность обмениваться данными, хотя и по одному сообщению за раз. Сначала сервер должен отправить сообщение, а затем клиент.
Вывод на консоль (на компьютере клиента ‘)
Enter the hostname of the server: *name*
Connected to chat server
Traceback (most recent call last):
File "******.py", line 71, in <module>
while1()
File "******.py", line 38, in while1
incoming_message=x.recv(1024)
OSError: [Errno 57] Socket is not connected
В выводе консоли говорится, что они сначала подключаются, поскольку он отображает Connected to chat server
сообщение, но затем они отключаются, поскольку сервер не может отправить какое-либо сообщение.
Если сервер пытается отправить сообщение после того, как сокет был отключен, вывод консоли:
Traceback (most recent call last):
File "******.py", line 43, in <module>
in_message=connection.recv(1024)
ConnectionResetError: [Errno 54] Connection reset by peer
Я полагаю, однако, что эта проблема решится сама собой после того, как проблема с сокетом будет решена.
Комментарии:
1. Вы должны попытаться создать минимальный пример, в котором все еще присутствует проблема, с которой вы сталкиваетесь. Я подозреваю, что проблема в том, что вы воссоздаете сокет в каждой функции вместо того, чтобы передавать подключенный сокет.
Ответ №1:
Большой намек на то, что не так, — это посмотреть, сколько раз вы вызываете socket.socket
в клиентском коде. Я вижу четыре разных места, где вы создаете новый сокет: дважды в while1
и дважды в portConnect
. Это, конечно, не то, что вы хотите. Ваш код не работает, потому что вы подключаете сокет, созданный в portConnect
, затем этот объект сокета выходит из области видимости при завершении функции. x
In portConnect
— это не то же самое, что x
in while1
.
Я бы передал x
в portConnect
вместо использования вновь созданного сокета:
def portConnect(h_name, port, x):
# Don't create a new socket here
connected = False
while connected == False:
# Also don't create a new socket here
. . .
Затем переместите вызов в portConnect
куда-нибудь, где x
находится область видимости, и вызовите его как:
portConnect(h_name, port, x)
Вы также, вероятно, хотите избавиться от x = socket.socket()
внутренней части while 1:
цикла.
Вы также можете создать его x
в portConnect
, а затем return
из функции. Вы можете обнаружить, что это имеет больше смысла.
Несколько побочных вещей:
-
while1
это очень плохое название для функции. Название должно описывать, что делает функция, а не подробности о ее реализации. -
while 1
более понятно, какwhile True
. -
Такие условия, как
while connected == False:
, более удобочитаемы и идиоматичны, какwhile not connected:
. Сравнение сTrue
иFalse
напрямую никогда не требуется.
Комментарии:
1. Теперь отправляется сообщение, но при попытке нового питания при запуске это происходит:
Traceback (most recent call last): File "/***", line 20, in portConnect x.connect((h_name,port)) ConnectionRefusedError: [Errno 61] Connection refused During handling of the above exception, another exception occurred: Traceback (most recent call last): ***", line 68, in <module> portConnect(h_name, port,x) ***.py", line 27, in portConnect portConnect(h_name,port,x) ***", line 20, in portConnect x.connect((h_name,port)) OSError: [Errno 22] Invalid argument
2. @user14303139 Дважды проверьте, что такое
h_name
иport
. Чтоh_name
вы используете?3. h_name не изменяется на протяжении всего этого процесса, даже при повторном входе в h_name отображается та же ошибка. Типы переменных точно такие же, как и в первый раз
4. @user14303139 В чем
port
заключается сбой?5. Когда сервер запускается на порту 8001 (например), клиент увидит, что h_name открыто, но не на этом порту, поэтому код увеличивает номер порта до 8001 (с исходного значения 8000, установленного в начале клиентского кода), это единственный аргумент, который изменяется. Даже если эта функция изменяется с рекурсивной только на цикл while, возникает та же проблема