Linux网络通信

您所在的位置:网站首页 connection函数详解 Linux网络通信

Linux网络通信

2024-06-13 20:22| 来源: 网络整理| 查看: 265

connect的使用和注意事项 connect的参数含义 阻塞模式下connect的返回值和参数设置 非阻塞下connect的返回值和参数设置

connect的参数含义

123#include ; #include ; int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);

在Linux中的socket编程中,建立网络连接是通过connect函数来完成的,函数原型为: int connect (int sockfd, struct sockaddr * serv_addr, int addrlen)

sockfd:该参数是通过调用socket()函数来获得socket的文件描述符并传入该位置。 serv_addr:该参数是可传入的实际结构体为sockaddr_in和sockadd_in6 sockaddr_in:该结构体存有将要connect的ipv6的网络地址以及端口和协议族 sockaddr_in6:该结构体存有将要connect的ipv6的网络地址以及端口和协议族 addrlen: 为传入参数sockaddr结构体的大小,该参数实际应该是一个传出参数。

阻塞模式下connect的返回值和参数设置

首先,阻塞和非阻塞不是connect函数的属性。而是通过socket的函数获取的文件描述符所指向的抽象文件的属性。 所以需要通过操作socket获取的文件描述符fd(file descriptor)来对其设置为非阻塞,默认情况下,socket文件的属性为阻塞的。

接下来是获取一个阻塞的socket文件描述符

12345678910111213141516        //这里以ipv6的connect连接为例,ipv4可自行百度         int fd = socket(AF_INET6,SOCK_STREAM,0);            //AF_INET:指定为ipv6协议族,SOCK_STREAM:面向流的连接,第三个为0就好,该参数是指定具体协议         //由于默认的socket就是阻塞的,所以可以直接将该获取的fd加入到connect的第一个参数中。即完成了第一个参数的设置 [cc]  //通过一个ipv6的地址字符串和端口获取一个sockaddr_in6     struct sockaddr_in6 addr6;      //定义一个sockaddr_in6     addr6.sin6_family = AF_INET6;       //指定该sockaddr_in6的协议为ipv6协议     addr6.sin6_port = htons(80);            //指定连接的端口,htons()函数是将一个本地字节序的short转为网络字节序的short     inet_pton(AF_INET6, "::1", ;addr6.sin6_addr);       //指定连接的ipv6地址,inet_pton是将ipv6的地址字符串转为网络字节序传输的字符串     //这样就完成了connect的第二个参数的设置         //获取sockaddr_in6的长度     int len = sizeof(sockaddr_in6);     //即完成了第三个参数的设置     //调用connect函数进行连接,即完成了整个过程: 连接成功flag返回0,连接失败flag返回-1     int flag = connect(fd,;addr6,len);

[/cc]

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 flag返回0时,表明该连接已经成功建立。 flag返回-1时,表明该连接发生了错误,即没有成功建立连接。 并会将发生的错误记录在一个全局变量errno中,其中errno的取值有: errno:

注:inet_pton和socket都有可能调用失败,从而需要对其返回值进行相应的错误处理

非阻塞下connect的返回值和参数设置

对于非阻塞的connect的连接,其不会在调用connect的时候进行阻塞,而是立即返回。如果返回0,说明调用connect的时候还没来得及让connect返回便已经建立了连接;而如果返回-1,errno会记录一个错误码,如果该错误码为EINPROGRESS。则说明该连接还正在建立,并不能说明该连接出错。一个非阻塞connect的简单测试。

1234567891011121314151617181920212223242526    int flag;     int fd = socket(AF_INET,SOCK_STREAM,0);     flag = fcntl(connect_fd,F_GETFL,0);     //获取文件描述符的属性     fcntl(connect_fd, F_SETFL, flag|O_NONBLOCK);        //将文件描述符的属性设置为非阻塞     struct sockaddr_in addr={0};     addr.sin_family= AF_INET;     addr.sin_port = htons(80);     inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);     for(;;){         flag = connect(fd,&addr,len);       //fd被设置成了非阻塞的文件描述符         if(flag == 0){         printf("connect  success!\n");         break;         }else{             if(errno != EINPROGRESS){                 printf("connect error!"                          "errno:%d\n",errno);                 break;             }else{                 printf("connection is being established\n")                 sleep(1);                 continue;             }         }     } 12345678910111213141516171819202122232425

通常如果connect函数可以最终被调用成功会打印"connection is being established"和"connect success!"。 注意:fcntl函数对文件描述符进行设置和获取的时候需要对其返回值做校验

1                               

另外一篇文章解析,请点击!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3