📄 netutil.c
字号:
/*************************************************************************** * netutil.c * * Mon May 21 18:07:20 2007 * Copyright 2007 kf701 * Email <kf701.ye AT gmail.com> ****************************************************************************//* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <errno.h>#include <sys/time.h>#include <time.h>#include <sys/types.h>#include <sys/socket.h>#include <netdb.h>#include <fcntl.h>#include <sys/mman.h>#include <sys/stat.h>#include "kf701.h"/** * @brief open a TCP socket and connect to ip:port * @param ip server ip * @param port server port * @param timeout seconds for time out * @retval socket fd success * @retval -1 error */int connect_nonblock(char *ip,uint16_t port,uint32_t timeout){ int sockfd, flags, n; int sock_error; socklen_t len; fd_set rset, wset; struct timeval tval; struct sockaddr_in servaddr; struct hostent *hent; if (NULL == ip) return -1; sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) return -1; hent = gethostbyname(ip); if (NULL == hent) { close(sockfd); return -1; } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(port); servaddr.sin_addr = *(struct in_addr *)hent->h_addr; flags = fcntl(sockfd, F_GETFL, 0); if (-1 == flags) { close(sockfd); return -1; } if ( -1 == fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) ) { close(sockfd); return -1; } if ( (n = connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) ) if (errno != EINPROGRESS) { close(sockfd); return -1; } /* Do whatever we want while the connect is taking place. */ if ( 0 == n) return sockfd; /* connect completed immediately */ FD_ZERO(&rset); FD_SET(sockfd, &rset); wset = rset; tval.tv_sec = timeout; tval.tv_usec = 0; if ( select(sockfd+1, &rset, &wset, NULL, timeout ? &tval : NULL) == 0 ) { close(sockfd); /* timeout */ return -1; } if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) { len = sizeof(sock_error); if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &sock_error, &len) < 0) { close(sockfd); return -1; } if (sock_error) { errno = sock_error; close(sockfd); return -1; } } else { //printf("select error: sockfd not set"); close(sockfd); return -1; } /* restore file status flags */ if ( fcntl(sockfd, F_SETFL, flags) < 0 ) { close(sockfd); return -1; } return sockfd; }/** * @brief open a TCP socket listen on port * @param port listen port * @retval socket fd success * @retval -1 error */int open_listenfd(uint16_t port){ int listenfd, optval = 1; struct sockaddr_in serveraddr; if( ( listenfd = socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) { return -1; } if( setsockopt( listenfd, SOL_SOCKET, SO_REUSEADDR, (const void*)&optval, sizeof(int) ) < 0 ) goto error; bzero(( char* )&serveraddr, sizeof(serveraddr) ); serveraddr.sin_family = AF_INET; serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); serveraddr.sin_port = htons((uint16_t)port); if( bind( listenfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr) ) < 0 ) { goto error ; } if( listen( listenfd, 5 ) < 0 ) goto error; return listenfd;error: close(listenfd); return -1;}/** * @brief open a UDP socket listen on port * @param port listen port * @retval socket fd success * @retval -1 error */int open_udp( uint16_t port){ int fd; fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if ( fd == -1 ) { sys_message("%s,%d:socket error\n",__func__,__LINE__); return -1; } struct sockaddr_in addr; memset((char*) &(addr),0, sizeof((addr))); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(port); if ( bind( fd,(struct sockaddr*)&addr, sizeof(addr)) != 0 ) { switch (errno) { case 0: { sys_message("%s,%d:bind error\n",__func__,__LINE__); return -1; } case EADDRINUSE: { sys_message("%s,%d:port in use\n",__func__,__LINE__); return -1; } break; case EADDRNOTAVAIL: { sys_message("%s,%d:Cannot assign requested address\n",__func__,__LINE__); return -1; } break; default: { sys_message("%s,%d:error=%s\n",__func__,__LINE__,strerror(errno)); return -1; } break; } } return fd;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -