Go 在TCP连接的端口上发送UDP数据包
我有一个Golang TCP服务器,即Go 在TCP连接的端口上发送UDP数据包,go,udp,Go,Udp,我有一个Golang TCP服务器,即net.TCPConn,连接在一个端口上,除了TCP流之外,该端口还必须接收UDP数据包并用UDP数据包进行响应。传入的UDP数据包在服务器上弹出(从net.TCPConn.Read()),但我不知道如何再次发送UDP数据包。所有UDP写入方法仅适用于net.UDPConnnet.UDPConn.writemsgludp()诱人地谈论它是应用于连接的套接字还是非连接的套接字,但我不知道如何从net.TCPConn派生net.UDPConn;我尝试将net.T
net.TCPConn
,连接在一个端口上,除了TCP流之外,该端口还必须接收UDP数据包并用UDP数据包进行响应。传入的UDP数据包在服务器上弹出(从net.TCPConn.Read()
),但我不知道如何再次发送UDP数据包。所有UDP写入方法仅适用于net.UDPConn
net.UDPConn.writemsgludp()
诱人地谈论它是应用于连接的套接字还是非连接的套接字,但我不知道如何从net.TCPConn
派生net.UDPConn
;我尝试将net.TCPConn
转换为net.UDPConn
,但这会引起恐慌
正确的方法是什么
仅供参考,我确实在同一端口上打开了一个UDP侦听器(“因为另一端的客户端可以选择在完全无连接模式下运行”),但由于套接字连接后,UDP数据包到达TCP服务器而不是UDP服务器,我想将UDP响应发送回同一个端口,而不是以某种邪恶的方式将两者混为一谈。还是说不整洁就是答案
编辑:这里是关于系统设计的一个词:这个UDP数据包的目的是测试这个套接字上的连接(服务器只是回显它)。套接字是一个[希望]已建立的SSH端口转发隧道,因此我不想使用另一个套接字,因为这不会测试我要测试的内容(即,套接字和SSH隧道都是打开的;SSH端口转发隧道的一个缺点是,由于应用程序连接到
localhost
,套接字将立即报告已连接,即使服务器当时没有实际连接)。SSH隧道承载TCP流量流,我特别希望使用UDP进行此操作,因为我不希望我的UDP连接测试被卡在TCP流量队列后面;在此应用程序中,计时非常重要,UDP数据包携带时间戳来测量它。如果是有效的套接字操作,Go必须有办法完成…? 如果您只想将UDP数据包发送到通过TCP首先到达您的应用程序的“客户端”,那么您可能需要获得远程:
然后假设此客户端也是服务器,并在1234
ServerAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:1234", addr))
然后,您可以通过执行以下操作进行回复:
conn, err := net.DialUDP("udp", nil, ServerAddr)
if err != nil {
log.Fatal(err)
}
defer close(conn)
buf := []byte("ping")
_, err = conn.Write(buf)
我不知道这是否正是你想要的,但希望能给你更多的想法。在所有问题的讨论变得清晰之后
@JimB说得很对,您不能在TCP端口上发送UDP数据包。我认为这是可能的原因是sendto()
的定义说:
如果在连接模式(SOCK\u STREAM
)上使用了sendto()
,
SOCK\u SEQPACKET
)套接字,参数dest\u addr
和addrlen
为
已忽略(如果未忽略,则可能会返回错误EISCONN
)
NULL
和0),并且在套接字启动时返回错误ENOTCONN
实际上没有连接
…当我在TCP连接的端口上调用sendto()
时,我发送的数据确实出现在我的Golangnet.TCPConn
端点。然而,在这种情况下发生的情况是,sendto()
实际上已经成为send()
的别名,尽管调用了sendto()
,发送的数据实际上是在TCP数据包中传输的,而不是UDP数据包。使用netcat-u$host$port
向服务器发送UDP流量和netcat$host$port
向服务器发送TCP流量证明了这一点:前者没有在net.TCPConn
端点生成任何数据,而他是后者
正确的方法是,客户端在同一端口上同时向服务器打开TCP和UDP套接字,而服务器同时侦听TCP和UDP“连接”(UDP连接当然不是连接,它只是与本地端口号的关联)在同一端口上。然后TCP服务器处理我的流,UDP服务器处理我的UDP测试/测量数据包,两者都通过同一SSH端口转发隧道。UDP不建立连接,通常在使用UDP时,直接处理单独寻址的数据包,因此在接收和发送每个数据包时您还需要接收或通知对等方的IP+端口,以了解您正在与谁通话或信息来自谁。有两个系统调用用于此操作,
recvfrom()
和sendto()
,我不知道如何实现此功能,但我非常确定net.TCPConn.Read()
根本不适用于UDP。您无法从TCP连接发送或接收UDP数据包。如果您需要发送UDP数据包,请使用UDP连接。我知道UDP是无连接的,但它可以通过连接的套接字发送UDP数据包;您只需将目标地址保留在发送到()
它明白了你的意思。我知道这一点,因为这正是链接的另一端(用C编码)在这种情况下所做的。当然,Golang在其net
实现中允许了非常正常的套接字操作!?中的注释暗示了它,我只是不知道它是如何工作的。你不能发送UDPTCP连接上的数据包,这没有任何意义。我可以向您保证,您没有在TCP连接上接收到UDP数据包,并且由于ssh隧道是TCP,您无法向其发送UDP数据包。可能有一个UDP套接字侦听同一端口号,但它与TCP连接完全分离。
conn, err := net.DialUDP("udp", nil, ServerAddr)
if err != nil {
log.Fatal(err)
}
defer close(conn)
buf := []byte("ping")
_, err = conn.Write(buf)