首页 > 解决方案 > 如何将 UDP 数据包发送到我在 Python (3.7.3) 中创建的 UDP 服务器?

问题描述

请让我开始说我是 Python 新手(CS 一年级学生),这是我正在学习的第一门编程语言。

我有一个包含 2 个部分的作业;客户端和服务器

在服务器端,我试图:

1)创建一个不断等待UDP消息并等待两个不同的UDP消息(string1和string2)的服务器

2) 然后它将 2 个数据包的字符串连接为 string3,并在单个 UDP 数据包中将其发送给客户端并重新开始。

例如,服务器接收字符串 1 和字符串 2 作为 pinea 和 pples,将菠萝构造为字符串 3 并将字符串 3 发送给客户端

在客户端,我需要编写一些代码:1)在启动时提示客户端输入字符串#

2) 将该字符串拆分为 2(如果 n 为偶数,则为 n/2,如果 n 为奇数,则为 (n+1)/2 和 (n-1)/2)

3) 在单独的 UDP 数据包中等待来自服务器的字符串

4) 检查来自服务器的字符串是否 = 两个拆分字符串的连接

5) 显示最终答案的结果

例如,用户输入字符串为菠萝,客户端发送字符串 1 和字符串 2 为 pinea 和 pples;然后从服务器接收 string3 作为菠萝并检查 string3==string1+string2。

我试图弄清楚为什么在设置我的服务器后我无法向服务器发送数据包和从服务器发送数据包。

我目前正在使用 Python IDLE 3.7.3,我已经观看了很多视频并阅读了其他一些堆栈溢出论坛,但无法确定问题,如前所述,我是初学者,非常感谢任何帮助

这是我的代码:

对于我拥有的服务器:

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
address = ("127.0.0.1", 5002)
sock.bind (address)

while True:
    data,addr= sock.recvfrom(1024)
    print (data)
    print (addr)

sock.listen(5)

我的客户端代码如下:

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s=str(input("Please input a word: "))
string1 = s[:len(s)//2]
string2 = s[:len(s)//2:] 
message1= string1.encode()
message2= string2.encode()
sock.sendto(message1+message1,("127.0.0.1",5002))
received= sock.recv(1024)
received==string1+string2

while True:
    print (message1, message2)
    print (received)

当我尝试运行我的客户端代码时,我目前收到错误消息“远程主机强制关闭现有连接”。

非常感谢(这也是我第一次使用 Stack Overflow,所以如果我在帖子中做了任何不恰当的事情,请告诉我,以便我纠正)

标签: pythonserverudppacket

解决方案


您的代码似乎结构奇怪,while循环不正确/做无意义的事情等...

我已经整理/重写了您的代码,以便对我有用。我正在使用上下文管理器以便很好地清理套接字。对于服务器,类似:

import socket

with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
    sock.bind(("127.0.0.1", 5002))

    while True:
        data, addr = sock.recvfrom(8192)
        print(data, addr)
        sock.sendto(b"hi from server", addr)

和客户:

import socket

with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
    sock.connect(("127.0.0.1", 5002))

    sock.send(b"hi from client")
    print(sock.recvfrom(8192))

UDP 显然是“无连接”的,但调用connect允许执行一次名称解析,而不是每次send. 为了简单起见,我还对发送的消息进行了硬编码。

在调试时,它有助于消除尽可能多的复杂性,在这种情况下,读取输入似乎与网络代码无关。

我还建议使用socket.getaddrinfo这样您的代码可以更轻松地使用 IPv6,但这是一个单独的问题。


推荐阅读