2

UDP 的“无连接”方面让我陷入了循环......

如果我将 UDP 套接字设置为 INADDR_ANY,然后将其绑定到本地机器上的端口 33445,则机器将接受来自各种客户端的传入连接。所有这些连接都将由那个套接字提供服务,因为这不是 TCP,我无法生成新的子套接字来直接处理每个连接。我可以从他们的最新消息中回复任何、部分或所有这些连接的客户。

所以对我来说事情变得有点模糊的地方就在这里......

我是否也可以随时向这些客户中的任何一个发送消息?还是我只能发送响应 recvfrom() 的消息?

另外,如果我希望该服务器(当它为客户端提供服务时)连接到另一台服务器并就其他事情进行对话,我认为我需要为此创建一个新套接字?我不能只使用现有的服务器套接字并指定一个新的目标地址吗?

非常感谢这个美好的社区。

编辑:让我换一种说法。似乎我只能使用绑定套接字来响应以前在该套接字上到达我的客户端。要启动与新主机的对话,我不能简单地为此目的使用绑定套接字吗?我必须创建一个新套接字才能访问正在侦听的服务器,对吗?

4

2 回答 2

3

UDP 套接字可以在两种不同的模式下运行:

  • 默认未连接模式:接收所有发送到您进程的端口/地址的数据报;您需要为每次发送指定目标地址。
  • 连接模式:仅接收从您连接的地址/端口发送的数据报;您无需在每次发送时指定目标地址。

这是对已连接的 UDP 套接字的一个小回顾。

编辑:

这是一个小的 python UDP 服务器,它接受来自任何客户端的数据包并将它们复制到第二个服务器。一切都通过一个未连接的 UDP 套接字完成。

#!/usr/bin/env python
import sys, socket, string

if len( sys.argv ) != 4:
        print "Usage: udptee <local-listen-port> <copy-host> <copy-port>"
        exit( 1 )

copy = ( sys.argv[2], int( sys.argv[3] ))

s = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
#s.bind(( 'localhost', int( sys.argv[1] )))
s.bind(( '', int( sys.argv[1] )))

print "listening on ", s.getsockname()
print "copying to", copy

while True:
        line, addr = s.recvfrom( 1024 )
        print "received: ", line, " from ", addr
        s.sendto( line, addr ) # echo to source
        s.sendto( line, copy ) # copy to tee
        if string.strip( line ) == "exit": break

print "Goodbye and thanks for all the fish"
s.close()

在一个终端中运行它:

~$ ./udptee 9090 <IP-of-copy-server> 9999

然后netcat在第二学期以服务器模式开始。这个将接受数据报的副本:

# this used to be "nc -ul 127.0.0.1 9999" which only listened on loopback
~$ nc -ul 9999

在第三学期启动netcat客户端以将内容发送到第一台服务器:

~$ nc -u <IP-of-tee-server> 9090

开始输入并看到两个服务器都回显您输入的内容。

于 2010-08-09T13:50:49.863 回答
1

UDP 套接字未连接到远程主机或客户端,因此您需要做的就是使用 sendto() 使用目标地址和您已初始化的 UDP 套接字。所以是的,只要您正确设置了 UDP 套接字,您就可以随时使用 UDP 套接字发送消息。只需在您正在使用的 sockaddr 结构中设置接收地址。如果接收部分在您发送消息的端口上绑定了一个 UDP 套接字,那么它将接收它。

在第二个问题上,这完全取决于与第二台服务器的对话是否使用不同的端口。如果它使用相同的端口,则无需创建另一个 UDP 套接字。您只需要以某种方式将服务器 1 从其客户端获取的消息与从服务器 2 获取的消息分开即可。

生病建议看看 Beej 的优秀指南第 5.8 和 6.3 章。

Beej 的网络编程指南

于 2010-08-09T08:54:21.587 回答