Python中的套接字编程

Python中的套接字编程,python,sockets,udp,Python,Sockets,Udp,我正在使用python进行概念验证,它模拟使用套接字发送UDP数据包的服务器/客户端通信。我可以很容易地进行简单的客户机到服务器和回客户机通信,但我正试图在这种通信中引入一个“中间人”。从概念上讲,问题可以描述为,如果“Joe”是主要客户,他将向“Steve”发送消息,Steve是中间人,他将处理该消息,然后将消息发送给“Carol”,Carol作为服务器处理新消息,并将响应发送回中间人“Steve”。最终,中间人将把这个信息发送到其他地方,但目前我并不担心这一点 我当前的代码如下所示: “乔”

我正在使用python进行概念验证,它模拟使用套接字发送UDP数据包的服务器/客户端通信。我可以很容易地进行简单的客户机到服务器和回客户机通信,但我正试图在这种通信中引入一个“中间人”。从概念上讲,问题可以描述为,如果“Joe”是主要客户,他将向“Steve”发送消息,Steve是中间人,他将处理该消息,然后将消息发送给“Carol”,Carol作为服务器处理新消息,并将响应发送回中间人“Steve”。最终,中间人将把这个信息发送到其他地方,但目前我并不担心这一点

我当前的代码如下所示:

“乔”(原始客户)看起来像 “史蒂夫”(中间人)看起来像 “卡罗尔”(服务器)看起来像 目前我可以从Joe那里收到一条消息,但它仍挂在发送到服务器Carol的过程中。我对socket编程一无所知,因此非常感谢您的帮助

编辑以澄清 使用Python 3.4


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
    encode
    行为取决于系统配置。与许多其他潜在问题一样,在Python3.x中通过强制使用UTF-8(在2.x中,您必须显式地请求UTF-8)解决了这一问题。在您的情况下,只要只发送ASCII字符就可以了
  • while(1):
    在Python中看起来很奇怪-为什么参数后面有空格,为什么是括号。为什么不
    而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')