udp连接失败是什么原因?

udp连接失败是什么原因?,第1张

udp连接不上,是3100错误!也就是你的防火墙设置的问题!要修改路由器中的udp设置!上边他们讲的都难了点,如果不是高手,很多人不知道,就算你看懂了,没准你还不知道具体怎么弄。

我告诉你一个办法。绝对有效!

玩游戏的时候把你本机的的防火墙关掉就行了。不玩游戏的时候在开启!这个是最简单的!而且绝对的快速有效!

先登陆QQ,在系统设置的高级选项里选择"UDP"类型,服务器IP地址就填你需要登陆的地址QQ服务器地址,以下是其地址,任意选择一个UDP的

QQ服务器分为三类:

1、UDP 8000端口类18个:速度最快,服务器最多。

QQ上线会向这些服务器发送UDP数据包,选择回复速度最快的一个作为连接服务器。

61.144.238.145

61.144.238.146

61.144.238.156

61.144.238.150

202.104.129.251

202.104.129.254

202.104.129.252

202.104.129.253

61.141.194.203

202.96.170.166

218.18.95.221

219.133.45.15

61.141.194.200

61.141.194.224

202.96.170.164

202.96.170.163

219.133.40.216

218.18.95.209

2、TCP HTTP连接服务器5个,使用HTTP 80 和443端口连接

这4个服务器名字均以tcpconn开头,域后缀是tencent.com,域名与IP对应为

tcpconn tcpconn3 218.17.209.23

tcpconn2 tcpconn4 218.18.95.153

61.141.194.227

218.18.95.171 218.18.95.221

3、会员VIP登陆服务器,使用HTTP 443安全连接

服务器IP 218.17.209.42

在前面的基础篇中,我们已经接触到了 UDP 数据报协议相关的知识,在我们的脑海里,已经深深印上了“UDP 等于无连接协议”的特性。那么看到这一讲的题目,你是不是觉得有点困惑?没关系,和我一起进入”已连接“的 UDP 的世界,回头再看这个标题,相信你就会恍然大悟。

我们先从一个客户端例子开始,在这个例子中,客户端在 UDP 套接字上调用 connect 函数,之后将标准输入的字符串发送到服务器端,并从服务器端接收处理后的报文。当然,和服务器端发送和接收报文是通过调用函数 sendto 和 recvfrom 来完成的。

我对这个程序做一个简单的解释:

在没有开启服务端的情况下,我们运行一下这个程序:

看到这里你会不会觉得很奇怪?不是说好 UDP 是“无连接”的协议吗?不是说好 UDP 客户端只会阻塞在 recvfrom 这样的调用上吗?怎么这里冒出一个“Connection refused”的错误呢?

别着急,下面就跟着我的思路慢慢去解开这个谜团。

从前面的例子中,你会发现,我们可以对 UDP 套接字调用 connect 函数,但是和 TCP connect 调用引起 TCP 三次握手,建立 TCP 有效连接不同,UDP connect 函数的调用,并不会引起和服务器目标端的网络交互,也就是说,并不会触发所谓的”握手“报文发送和应答。

那么对 UDP 套接字进行 connect 操作到底有什么意义呢?

其实上面的例子已经给出了答案,这主要是为了 让应用程序能够接收”异步错误“的信息

如果我们回想一下第 6 篇不调用 connect 操作的客户端程序,在服务器端不开启的情况下,客户端程序是不会报错的,程序只会阻塞在 recvfrom 上,等待返回(或者超时)。

在这里,我们通过对 UDP 套接字进行 connect 操作,将 UDP 套接字建立了”上下文“,该套接字和服务器端的地址和端口产生了联系,正是这种绑定关系给了操作系统内核必要的信息,能够将操作系统内核收到的信息和对应的套接字进行关联。

我们可以展开讨论一下。

事实上,当我们调用 sendto 或者 send 操作函数时,应用程序报文被发送,我们的应用程序返回,操作系统内核接管了该报文,之后操作系统开始尝试往对应的地址和端口发送,因为对应的地址和端口不可达,一个 ICMP 报文会返回给操作系统内核,该 ICMP 报文含有目的地址和端口等信息。

如果我们不进行 connect 操作,建立(UDP 套接字——目的地址 + 端口)之间的映射关系,操作系统内核就没有办法把 ICMP 不可达的信息和 UDP 套接字进行关联,也就没有办法将 ICMP 信息通知给应用程序。

如果我们进行了 connect 操作,帮助操作系统内核从容建立了(UDP 套接字——目的地址 + 端口)之间的映射关系,当收到一个 ICMP 不可达报文时,操作系统内核可以从映射表中找出是哪个 UDP 套接字拥有该目的地址和端口,别忘了 套接字在操作系统内部是全局唯一的 ,当我们在该套接字上再次调用 recvfrom 或 recv 方法时,就可以收到操作系统内核返回的”Connection Refused“的信息。

在对 UDP 进行 connect 之后,关于收发函数的使用,很多书籍是这样推荐的:

其实不同的 UNIX 实现对此表现出来的行为不尽相同。

在我的 Linux 4.4.0 环境中,使用 sendto 和 recvfrom,系统会自动忽略 to 和 from 信息。在我的 macOS 10.13 中,确实需要遵守这样的规定,使用 sendto 或 recvfrom 会得到一些奇怪的结果,切回 send 和 recv 后正常。

考虑到兼容性,我们也推荐这些常规做法。所以在接下来的程序中,我会使用这样的做法来实现。

一般来说,服务器端不会主动发起 connect 操作,因为一旦如此,服务器端就只能响应一个客户端了。不过,有时候也不排除这样的情形,一旦一个客户端和服务器端发送 UDP 报文之后,该服务器端就要服务于这个唯一的客户端。

一个类似的服务器端程序如下:

我对这个程序做下解释:

注意这里所有收发函数都使用了 send 和 recv。

接下来我们实现一个 connect 的客户端程序:

我对这个客户端程序做一下解读:

注意这里所有收发函数也都使用了 send 和 recv。

接下来,我们先启动服务器端程序,然后依次开启两个客户端,分别是客户端 1、客户端 2,并且让客户端 1 先发送 UDP 报文。

我们看到,客户端 1 先发送报文,服务端随之通过 connect 和客户端 1 进行了“绑定”,这样,客户端 2 从操作系统内核得到了 ICMP 的错误,该错误在 recv 函数中返回,显示了“Connection refused”的错误信息。

一般来说,客户端通过 connect 绑定服务端的地址和端口,对 UDP 而言,可以有一定程度的性能提升。

这是为什么呢?

因为如果不使用 connect 方式,每次发送报文都会需要这样的过程:

连接套接字→发送报文→断开套接字→连接套接字→发送报文→断开套接字 →………

而如果使用 connect 方式,就会变成下面这样:

连接套接字→发送报文→发送报文→……→最后断开套接字

我们知道,连接套接字是需要一定开销的,比如需要查找路由表信息。所以,UDP 客户端程序通过 connect 可以获得一定的性能提升。

在今天的内容里,我对 UDP 套接字调用 connect 方法进行了深入的分析。之所以对 UDP 使用 connect,绑定本地地址和端口,是为了让我们的程序可以快速获取异步错误信息的通知,同时也可以获得一定性能上的提升。

可以对一个 UDP 套接字进行多次 connect 操作吗? 你不妨动手试试,看看结果。

UDP协议经过connect之后,在通过sendto来发送数据报时不需要指定目的地址、端口,如果指定了目的地址、端口,那么会返回错误。通过UDP协议可以给同一个套接字指定多次connect操作,而TCP协议不可以,TCP只能指定一次connect操作。UDP协议指定第二次connect操作之后会先断口第一次的连接,然后建立第二次的连接。

如果想使用多播或广播,我们应该怎么去使用 connect 呢?

参考: https://blog.51cto.com/a1liujin/1699540

对于recvfrom函数,我们可以看成是TCP中accept函数和read函数的结合,前三个参数是read的参数,后两个参数是accept的参数。对于sendto函数,则可以看成是TCP中connect函数和send函数的结合,前三个参数是send的参数,后两个参数则是connect的参数。所以udp在发送和接收数据的过程中都会建立套接字连接,只不过每次调用sendto发送完数据后,内核都会将临时保存的对端地址数据删除掉,也就是断开套接字,从而就会出现循环。


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/218064.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-06
下一篇2023-04-06

发表评论

登录后才能评论

评论列表(0条)

    保存