1:UDP中可以使用connect系统调用
2:UDP中connect操作与TCP中connect操作有着本质区别.TCP中调用connect会引起三次握手,client与server建立连结.UDP中调用connect内核仅仅把对端ip&port记录下来.
3:UDP中可以多次调用connect,TCP只能调用一次connect.UDP多次调用connect有两种用途:1,指定一个新的ip&port连结.2,断开和之前的ip&port的连结.指定新连结,直接设置connect第二个参数即可.断开连结,需要将connect第二个参数中的sin_family设置成 AF_UNSPEC即可.
4:UDP中使用connect可以提高效率.原因如下:普通的UDP发送两个报文内核做了如下:#1:建立连结#2:发送报文#3:断开连结#4:建立连结#5:发送报文#6:断开连结
采用connect方式的UDP发送两个报文内核如下处理:#1:建立连结#2:发送报文#3:发送报文另外一点,每次发送报文内核都由可能要做路由查询.5:采用connect的UDP发送接受报文可以调用send,write和recv,read操作.当然也可以调用sendto,recvfrom.调用sendto的时候第五个参数必须是NULL,第六个参数是0.调用recvfrom,recv,read系统调用只能获取到先前connect的ip&port发送的报文.
UDP中使用connect的好处:1:会提升效率.前面已经描述了.2:高并发服务中会增加系统稳定性.原因:假设client A 通过非connect的UDP与server B,C通信.B,C提供相同服务.为了负载均衡,我们让A与B,C交替通信.A与 B通信IPa:PORTa <----> IPb:PORTbA与 C通信IPa:PORTa' <---->IPc:PORTc
假设PORTa与 PORTa'相同了(在大并发情况下会发生这种情况),那么就有可能出现A等待B的报文,却收到了C的报文.导致收报错误.解决方法内就是采用connect的UDP通信方式.在A中创建两个udp,然后分别connect到B,C.
connect函数不止作用与tcp连接,同样可以作用于udp连接.不过两者的作用不同.
tcp与udp的connect不同
tcp使用connect函数,客户端发起三次握手协议,在收到对端的确认ack和ack后返回.对端在收到客户端的确认ack后,accept返回.
udp使用connect函数,并没有发起三次握手协议(这本身就是tcp协议内容),内核会记录目的端的ip和port,如果本地没指定port话,内核会自动指定一个port.调用connect,并不会使udp建连.
以下转自http://blog.csdn.net/cdhql/article/details/42081029
使用or不使用connect函数的udp区别
原理:
无连接的udp
socket----->sendto()或recvfrom()
连接的udp(使用了connect)
socket----->connect()----->send()或recv(),read/write.(此时sendto,recvfrom仍可用)
性能:
未连接udp套接字上调用sendto时,内核暂时连接该套接字,发送数据包,然后断开连接.执行下面的步骤.
未链接UDP套接字:
1.链接套接字
2.输出第一个数据包
3.断开套接字
4.链接套接字
5.输出第2个数据包
6.断开套接字
已链接套接字
1.连接套接字
2.输出第一个数据包
3.输出第2个数据包.
n.断开套接口..
使用connect的变化
1.会返回异步错误给应用进程。
为什么调用connect后,会收到返回异步错误?
1)不管是否调用connect,对端关闭时,内核都会收到错误之前性能看,每次关闭,内核收到错误不知道向谁发送.
2)使用connect内核保持着相关套接字,会向相关套接字发送消息.最明显的就是每次未连接的udp使用sendto会向内核拷贝两次,而连接的udp,即使调用read和write都可以发送,由内核保证目的地址.当内核收到错误时,知道向谁传递这个错误.
3)这个错误形式是什么?icmp消息报文.返回udp port xxxx unreachable.正如1)所说,不论是否调用connect,内核都会收到icmp的错误消息包,对于调用connect的udp程序,read/recvfrom收到的错误,errno=111,ECONNREFUSED,解释为Connection refused.
2.发送:从调用connect以后就可以不使用recvfrom和sendto函数,可以用read和write函数替代.上一步所说由内核保存目的地址.
3.接收:没有链接的UDP套接口将会接受所有发送到绑定端口的数据(任何一个进程只要向UDP绑定端口发送数据,都会被没有链接的UDP套接口接受),已链接套接口只会接受链接的另一方的数据,不接受其它人发送过来的数据.当connect时只能接收目的端ip的数据.
4.已连接的udp套接字还可用来确定某个特定目的地的外出接口.由connect用到udp的一个副作用造成的.:内核选择本机ip地址(多个ip时,且未调用bind显示绑定).本地ip通过为目的ip搜索路由表获得外出接口以及选定接口主ip地址.
多次调用connect
一般有2个目的
1.为套接字指定新的IP和端口号
2.断开套接字.设置要链接的新套接字的地址族为AF_UNSPEC即可。这可能会返回一个错误,EAFNOSUPPORT错误,没有关系.断开套接字连接是在已连接的套接字只上.