Python中的套接字编程
我正在使用python进行概念验证,它模拟使用套接字发送UDP数据包的服务器/客户端通信。我可以很容易地进行简单的客户机到服务器和回客户机通信,但我正试图在这种通信中引入一个“中间人”。从概念上讲,问题可以描述为,如果“Joe”是主要客户,他将向“Steve”发送消息,Steve是中间人,他将处理该消息,然后将消息发送给“Carol”,Carol作为服务器处理新消息,并将响应发送回中间人“Steve”。最终,中间人将把这个信息发送到其他地方,但目前我并不担心这一点 我当前的代码如下所示: “乔”(原始客户)看起来像 “史蒂夫”(中间人)看起来像 “卡罗尔”(服务器)看起来像 目前我可以从Joe那里收到一条消息,但它仍挂在发送到服务器Carol的过程中。我对socket编程一无所知,因此非常感谢您的帮助 编辑以澄清 使用Python 3.4Python中的套接字编程,python,sockets,udp,Python,Sockets,Udp,我正在使用python进行概念验证,它模拟使用套接字发送UDP数据包的服务器/客户端通信。我可以很容易地进行简单的客户机到服务器和回客户机通信,但我正试图在这种通信中引入一个“中间人”。从概念上讲,问题可以描述为,如果“Joe”是主要客户,他将向“Steve”发送消息,Steve是中间人,他将处理该消息,然后将消息发送给“Carol”,Carol作为服务器处理新消息,并将响应发送回中间人“Steve”。最终,中间人将把这个信息发送到其他地方,但目前我并不担心这一点 我当前的代码如下所示: “乔”
Joe正在不间断地发送数据包,以模拟此概念验证所针对的实际应用程序。Joe将以大约1包/4ms的速率发送数据包,但我只关心最近的数据包。然而,由于从Steve到Carol的往返平均周转时间约为10毫秒,我原本想将Joe最近的数据包缓存在本地内存位置,并覆盖该位置,直到Steve准备好在Carol回复最后一个数据包后向她发送数据包。然而,对于这个简单的概念证明,我还没有尝试实现它。任何关于这方面的建议都会很有帮助。有多个故障会导致整体故障,其中一些故障并不明显(即,在其他地方发生故障之前,它会一直工作) 首先,目前他尽可能快地发送数据包。仅此一点就可能导致其他任何地方的重大数据包丢失(这可能是一件好事,因为您现在必须确保您的代码能够经受住数据包丢失)。除非你真的想给网络增加压力,否则在发送循环中使用类似的方式是合适的 更重要的是,史蒂夫的插座设置都搞砸了。他最多需要两个插座,而不是三个。按照目前的设置方式,carol向steve回复她从中获取数据包的IP地址和端口(这很合理),但steve在一个不同的套接字上读取数据,而该套接字从未向steve发送数据。 更糟糕的是,steve的
s3
端口实际上与carol使用的端口相同!既然你是。您只需从代码中删除对s3
的所有引用,然后专门使用s2
另一个问题是,您不处理数据包丢失。例如,如果steve和carol之间丢失了一个数据包,代码
# Send to "Carol"
s2.sendto(num.encode(), (hostRT, portRT))
# receive from "Carol"
d = s2.recvfrom(1024) # s3 in the original
将永远挂起,因为卡罗尔不会在丢失的包裹之后再发送任何新的包裹。如前所述,由于joe正在尽可能快地发送数据包,所以数据包丢失的可能性更大
要检测数据包丢失,有几个选项:
- 使用多个或来发送和接收。这将使您的程序更加复杂
- 切换到异步/非阻塞IO,在Python中使用高级或更低级的IO
- 设置并正确处理。这可能是目前最简单的选择,但相当有限
- 如果您确实需要可靠的通信,请切换到TCP
除了上述网络问题外,还有一些潜在的问题或不准确之处:
- 如果您使用的是Python2.x,字符串上的
和decode
行为取决于系统配置。与许多其他潜在问题一样,在Python3.x中通过强制使用UTF-8(在2.x中,您必须显式地请求UTF-8)解决了这一问题。在您的情况下,只要只发送ASCII字符就可以了encode
在Python中看起来很奇怪-为什么参数后面有空格,为什么是括号。为什么不while(1):
或而1:
而True:
- 你可以用它来产生很大的效果。而不是 数据=s1.recvfrom(1024) num=数据[0]。解码() addrVM=数据[1]
data, addrVM = s1.recvfrom(1024)
num = data.decode('utf-8')
谢谢你的回答。为了澄清,我使用的是Python 3.4。我试着卸下与“Carol”一起发送和接收的套接字,但现在通信挂在中间人处,再也无法发送到Carol。这可能是由数据包丢失引起的吗?由于UDP是无连接协议,有哪些方法可以检测到UDP数据包丢失?我还在我原来的帖子中添加了一些澄清。在删除
s3
之后,代码。记住,你必须在史蒂夫之前先开始卡罗尔,否则就行不通了。先开始卡罗尔,再开始史蒂夫,再开始乔的流程起了作用。我以前是执行乔,然后卡罗尔,然后史蒂夫。这可能是导致某些数据包丢失的原因吗?只要您在本地主机上运行此程序,您就不会看到明显的数据包丢失,因为数据包永远不会到达实际的网络,尽管当然没有保证。我已经用如何处理数据包丢失的简短列表修改了答案。当然,如果没有人在听这些信息包(例如,史蒂夫在卡罗尔起床之前发送了一些信息),它们就会丢失。我很感谢编辑。我使用UDP over TCP来提高速度,因为它将用于实时系统。
host = ''
port = 8752
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
print ("socket created")
s.bind((host, port))
print ("Socket bind complete")
while 1:
d = s.recvfrom(1024)
data = d[0].decode()
addr = d[1]
print(data)
reply = "Upper case client data = " + data.upper()
print(reply)
s.sendto(reply.encode(), addr)
print ("message[" + addr[0] + ":" + str(addr[1]) + '] - ' + data.strip())
s.close()
# Send to "Carol"
s2.sendto(num.encode(), (hostRT, portRT))
# receive from "Carol"
d = s2.recvfrom(1024) # s3 in the original
data, addrVM = s1.recvfrom(1024)
num = data.decode('utf-8')