udp connect

在udp 上使用connect 的情况:

  1. 需要获取icmp 的错误信息.

2.如果需要向同一个ip地址多次 sendto , 用以减少不断的连接,断开.提高性能

注意:

udp 的connect 只记录(注册)对端的套接字结构(ip,port) , 并不会像tcp 进行3次握手.所以无法第一时间获取连接错误;

这种称为有连接的udp套接字 也只能 发送/接受 connect中的指定的ip,port;

下面一个例子说明了 sendto 只是向内核缓冲区复制数据 就返回了. 并不会产生icmp错误信息

无connect 版本

int main(int argc, char**argv)
{
    int sockfd  = socket(AF_INET,SOCK_DGRAM,0); //udp
    struct sockaddr_in sin;
    memset(&sin,0,sizeof(sin));
    sin.sin_port = htons(PORT);    //没有服务器
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    char send[100],recv[100];
    int n = 0;
 
    while(1){
        n = read(0,send,100);
        n =sendto(sockfd,send,n,0,(SA*)&sin,sizeof(sin)); //发送到缓冲区就返回, 没有icmp错误信息
        printf("sendto return : %d\n" , n);
        n = recvfrom(sockfd,recv,100,0,0,0); // 此时将一直阻塞在这里 等待接受数据
        printf("recvfrom return :%d\n",n);
        recv[n]  =0;
        printf("buf : %s\n", recv);
    }
 
    return 0;
}

通过调用connect 后的代码, 把sendto , recvfrom 换成了read , write (不是一定要换,只是后2个函数参数少)

通过connect后的udp 套接字 可以收到icmp错误信息了, 在read返回后将产生错误, write仅仅是复制数据到缓冲区;

#include "util.h"
#include <netdb.h>
extern int h_errno;
 
 
int main(int argc, char**argv)
{
    int sockfd  = socket(AF_INET,SOCK_DGRAM,0);
    struct sockaddr_in sin;
    memset(&sin,0,sizeof(sin));
    sin.sin_port = htons(PORT);
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = inet_addr("127.0.0.1");
    char send[100],recv[100];
    int n = 0;
    puts("begin connect");
    int r = connect(sockfd,(SA*)&sin,sizeof(sin));  //udp的连接在这一步不会有问题  与 tcp不同, tcp会3次握手, udp没有
    if(r < 0){
        perror("connect error");
        return 0;
    }
    printf("connect return :%d , errno:%d\n", r, errno);
 
    while(1){
        n = read(0,send,100);
        n = write(sockfd,send,n);    //这里也不会有问题,仅仅发送到缓冲区.
        printf("sendto return : %d\n" , n);
 
        n = read(sockfd,recv,100);  //这里将返回错误Connection refused,这是没connect前所没有的
        if(n < 0){
            printf("***recvfrom return :%d ,error:%d\n",n,errno);
            perror("***read error");
        }  else {
            recv[n]  =0;
            printf("buf : %s\n", recv);
        }
    }
 
 
 
    return 0;
}
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页