Почему UDP-клиент не может получить сообщение? - PullRequest
0 голосов
/ 27 октября 2018

Просто новичок здесь.Клиент отправляет сообщение на сервер, используя sendto(), которое сервер может получить, используя recvfrom().Проблема возникает, когда сервер пытается отправить сообщение клиенту.Код клиента застревает на indata, add = sock.recvfrom(1024).Почему именно это происходит?

КОД СЕРВЕРА:

import socket
port = 8000
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
address = ('127.0.0.1',port)
try:
    s.bind(address)
except socket.error as e:
    print(e)
while True:
    data, add = s.recvfrom(1024)
    break
print(data.decode(), add)


fin = open("send.txt")
senddata = fin.read()
print(senddata)
try:
    s.sendto(senddata.encode(),address)
except socket.error as e:
    print(e)
s.close()

КОД КЛИЕНТА:

import socket

sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

port = 8000
msg = 'hello server'

sock.sendto(msg.encode(),('127.0.0.1',port))

while True:
    indata, add = sock.recvfrom(1024)
    break
f = open("received.txt", 'w')
f.write(indata.decode())
sock.close()

Следует ли использовать несколько портов, если клиент и сервер работают на одном компьютере?

Ответы [ 2 ]

0 голосов
/ 27 октября 2018

Сервер связывается с портом 8000 в вашем коде. Клиент получает произвольный номер порта (привязка не используется). Когда сервер отправляет на порт 8000, он отправляет самому себе.

Вам нужно два порта, и сервер должен знать, что использует клиент. Вызов recvfrom на сервере должен сообщить вам номер удаленного порта (но я не знаком с API-интерфейсом сокета Python, поэтому не могу сказать вам, как это сделать).

0 голосов
/ 27 октября 2018

Ваша проблема здесь:

s.sendto(senddata.encode(),address)

... address в данном случае это адрес сервера, поэтому сервер отправляет пакет обратно самому себе, а не клиенту. Когда я изменил выше, чтобы:

s.sendto(senddata.encode(),add)

... программа работала как задумано. (Вероятно, есть аргумент для более описательных имен переменных, например, clientAddress и serverAddress, чтобы избежать такого рода путаницы)

Должно ли использоваться несколько портов, если клиент и сервер бегать на одной машине?

Да, и фактически ваш код использует несколько портов. В частности, ваш сервер привязывает свой сокет к порту 8000, а ваш клиент (неявно) привязывает свой сокет к какому-либо другому номеру порта (поскольку вы никогда явно не вызываете bind() на клиентском сокете, что хорошо для этого варианта использования) .

...