异步connect

来源:互联网 发布:阿里二手域名 编辑:程序博客网 时间:2024/05/18 02:56
//关于tcp连接的异步connect实现流程如下://(1)设置socket连接为非阻塞.//(2)调用connect函数.返回0表明连接成功.如果返回-1,同时errno为EINPROGRESS表明正在建立连接.//(3)使用select , epoll等 , 当描述符可写的时候检查连接状态.#include <stdio.h>#include <fcntl.h>#include <sys/types.h>#include <sys/socket.h>#include <errno.h>#include <sys/epoll.h>#include <netinet/in.h>#include <string.h>void setnonblock(int fd){    int flags = fcntl(fd, F_GETFL);    fcntl(fd, F_SETFL, flags | O_NONBLOCK);}int main(){const char* ip = "127.0.0.1";short port = 9999;//设置连接地址struct sockaddr_in addr;socklen_t socklen = sizeof(struct sockaddr_in);memset(&addr , 0 , sizeof(struct sockaddr_in));addr.sin_family = AF_INET;addr.sin_addr.s_addr = inet_addr(ip);addr.sin_port = htons(port);//创建描述符int fd = socket( AF_INET , SOCK_STREAM , 0);if (fd < 0){printf("socket() error\n");return -1;}//设置描述符为非阻塞setnonblock(fd);//连接int res;res = connect(fd , (struct sockaddr*)&addr , socklen);if (res == 0){printf("connect ok(1)\n");} else if (res == -1 && errno != EINPROGRESS){printf("connect err(1)\n");close(fd);return -1;} else {int epfd;//创建epoll描述符epfd = epoll_create(1024);if ( (epfd = epoll_create(1024) ) == -1){printf("epoll_create() err\n");close(fd);return -1;}//添加关注事件struct epoll_event ev;ev.events = EPOLLOUT;ev.data.fd = fd;epoll_ctl( epfd , EPOLL_CTL_ADD , fd , &ev);//编写网络程序的时候,epoll是程序的主循环.我们这里为了测试,连接上或connect超时(75秒)就break掉.//正常的流程是写一个处理connect结果的回调函数.int event_max = 1;struct epoll_event events[event_max];int i;while (1){res = epoll_wait( epfd , events , event_max , -1);if (res > 0){for ( i = 0 ; i < res ; i++){if ( events[i].data.fd == fd && ( events[i].events & EPOLLOUT) ){ //29(EPOLLOUT|EPOLLERR|EPOLLHUP)  //4(EPOLLOUT)//检查是否连接成功int optval;socklen_t optlen = sizeof(optval);int res1 = getsockopt(fd, SOL_SOCKET, SO_ERROR, &optval, &optlen);if ( res1 < 0 || optval){close(fd);close(epfd);printf("connect err(2)\n");return -1;} else {printf("connect ok(2)\n");}}}break;}}close(fd);close(epfd);}}

0 0
原创粉丝点击