UDP的connect
Posted tianzeng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UDP的connect相关的知识,希望对你有一定的参考价值。
UDP的connect没有三次握手过程,内核只是检测是否存在立即可知的错误(如一个显然不可达的目的地),
记录对端的的IP地址和端口号,然后立即返回调用进程。
未连接UDP套接字(unconnected UDP socket):新创建UDP套接字默认如此;
已连接UDP套接字(connected UDP socket):对UDP套接字调用connect的结果。
对于已连接UDP套接字,与默认的未连接UDP套接字相比:
1)再不能给输出操作指定目的IP地址和端口号。
sendto改用write或send,写到已连接UDP套接字上的任何内容都自动发送到由connect指定的协议地址(如IP地址和端口号)。
已连接UDP套接字调用sendto,不能指定目的地址。其第五个参数必须为空指针,第六个参数应为0或不考虑。
2)可不使用recvfrom以获悉数据报的发送者,改用read、recv或recvmsg。
在已连接UDP套接字上,由内核为输入操作返回的数据报只有来自connect所制定协议地址的数据报。
这样就限制一个已连接UDP套接字能且仅能与一个对端交换数据报。
3)由已连接UDP套接字引发的异步错误会返回给它们所在的进程,而未连接UDP套接字不接受任何异步错误。
POSIX规范指出,在未连接UDP套接字上不指定目的地址的输出操作应该返回ENOTCONN,而不是EDESTADDRREQ。
应用进程首先调用connect指定对端的IP地址和端口号,然后使用read和write与对端进程交换数据。
来自任何其他IP地址或端口的数据报不投递给这个已连接套接字,UDP将丢弃它们并生成相应的ICMP端口不可达错误。
UDP客户进程或服务器进程只在使用自己的UDP套接字与确定的唯一对端进行通信时,才可以调用connect。
调用connect的通常是UDP客户,不过有些网络应用中的UDP服务器会与单个客户长时间通信(如TFTP),此时客户和服务器都有可能调用connect。
DNS客户、服务器与connect函数的例子:
用于一个已连接UDP套接字的进程可出于以下目的之一会再次调用connect:
1)指定新的IP地址和端口号
2)断开套接字
性能:当进程知道自己要给同一个目的地址发送多个数据报时,显式连接套接字效率更高。
而临时连接未连接的UDP套接字大约会消耗每个UDP传输三分之一的开销
void dg_cli(FILE *fp, int sockfd, SA *pservaddr, socklen_t servlen) { int n; char sendline[MAXLINE], recvline[MAXLINE + 1]; if (connect(sockfd, (SA*)pservaddr, servlen) < 0){ cout<<"conn error!"<<endl; exit(0); } else cout<<"conn succ!"<<endl; while (fgets(sendline, MAXLINE, fp) != NULL){ if (write(sockfd, sendline, strlen(sendline)) < 0){ cout<<"write error"<<endl; exit(0); } if ( (n = read(sockfd, recvline, MAXLINE)) < 0){ cout<<"read error"<<endl; exit(0); } recvline[n] = 0; fputs(recvline, stdout); bzero(sendline, MAXLINE); bzero(recvline, MAXLINE); } }
以上是关于UDP的connect的主要内容,如果未能解决你的问题,请参考以下文章
七个办法只有一个有效:200 PORT command successful. Consider using PASV.425 Failed to establish connection.(代码片段
在 UDP 套接字上多次调用 connect() 以发送到不同的目标地址 - 有效吗?
在 UDP 套接字上使用 sendto()/recvfrom() 而不是 connect()/send()/recv() 的目的是啥?
sh 来自https://support.asperasoft.com/hc/en-us/articles/216126068-UDP-connectivity-testing