UDP的connect函数

UDP的connect没有三次握手过程,内核只是检测是否存在当即可知的错误(如一个显然不可达的目的地),服务器

记录对端的的IP地址和端口号,而后当即返回调用进程。网络

 

未链接UDP套接字(unconnected UDP socket):新建立UDP套接字默认如此;异步

已链接UDP套接字(connected UDP socket):对UDP套接字调用connect的结果。socket

 

对于已链接UDP套接字,与默认的未链接UDP套接字相比:函数

1)再不能给输出操做指定目的IP地址和端口号。性能

sendto改用write或send,写到已链接UDP套接字上的任何内容都自动发送到由connect指定的协议地址(如IP地址和端口号)。spa

已链接UDP套接字调用sendto,不能指定目的地址。其第五个参数必须为空指针,第六个参数应为0或不考虑。指针

2)可不使用recvfrom以获悉数据报的发送者,改用read、recv或recvmsg。code

在已链接UDP套接字上,由内核为输入操做返回的数据报只有来自connect所制定协议地址的数据报。blog

这样就限制一个已链接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);
    }
}
相关文章
相关标签/搜索