Linux网络通信 |
您所在的位置:网站首页 › connection函数详解 › Linux网络通信 |
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 |