__int32 connect_nob(__int32 sockfd, const SA* saptr, socklen_t salen, __int32 nsec) { __int32 n, error; socklen_t len; fd_set rset, wset; struct timeval tval; if (set_sock_block(sockfd, false) != 0) return -1; error = 0; if (( n = connect(sockfd, saptr, salen)) < 0) { #ifdef WIN32 if (getneterror() != 10035) // 非阻塞连接的正常错误 #else if (errno != EINPROGRESS) #endif return -1; } if (n == 0) goto DONE; //connect completed immediately FD_ZERO(&rset); FD_SET (sockfd, &rset); wset = rset; tval.tv_sec = nsec; tval.tv_usec = 0; if ((n = select(sockfd+1, &rset, &wset, NULL,nsec?&tval:NULL)) == 0) { closesocket(sockfd); #ifndef WIN32 errno = ETIMEDOUT; #endif return -1; } if (FD_ISSET (sockfd, &rset) || FD_ISSET(sockfd, &wset)) { len = sizeof(error); if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char*)&error, &len) < 0) return -1; } else return -1; DONE: set_sock_block(sockfd, true); if (error) { closesocket(sockfd); errno = error; return -1; } return 0; }
void im_connection::connect(const char* host, const char* serv) { _host = host; _serv = serv; _state = LIBIM_DISCONNECTED; _fd = tcp_connect(host, serv); if (_fd == -1) { if (_ops->network_error) _ops->network_error(this, getneterror()); return; } _state = LIBIM_CONNECTED; set_sock_block(_fd, false); _re = event_new(base, _fd, EV_READ|EV_PERSIST, read_cb, (void*)this); _we = event_new(base, _fd, EV_WRITE|EV_PERSIST, write_cb, (void*)this); event_add(_re, NULL); event_add(_we, NULL); _in = evbuffer_new(); _out = evbuffer_new(); if (_account->_imp->connect_cb) _account->_imp->connect_cb(this); if (_ops->network_connected) _ops->network_connected(this); }
int do_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen, int timeout) { set_sock_nonblock(sockfd); // Trying to connect with timeout int result = connect(sockfd, serv_addr, addrlen); if (result < 0) { // Not connected if (errno != EINPROGRESS) { // Not in progress return -1; } else { // Wait a timeout ms for socket to become ready to write into struct pollfd fdset[1]; fdset[0].fd = sockfd; fdset[0].events = POLLOUT | POLLERR | POLLHUP | POLLNVAL | POLLRDHUP; do { int fdready = poll(fdset, 1, timeout); if (fdready == -1 && errno == EINTR) continue; if (fdready < 1 || (fdready == 1 && fdset[0].revents != POLLOUT)) { // Timeout || error // Get socket error unsigned int err_val=0, sz = sizeof(int); getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)(&err_val), &sz); errno = err_val; if (!errno) // It can't be success, so simulate timeout errno = ENETDOWN; return -1; } break; } while (1); } } set_sock_block(sockfd); return 0; }
/***************************************************************************** Prototype : main_loop Description : main loop for cam ctrl server Input : CamCtrlSrvEnv *envp Output : None Return Value : static Calls : Called By : History : 1.Date : 2012/4/23 Author : Sun Modification : Created function *****************************************************************************/ static Int32 main_loop(CamCtrlSrvEnv *envp) { int ret = E_NO; Bool exit = FALSE; int listenSock, udpScok, fdMax; fd_set rdSet; UdpProcEnv udpProcEnv; /* alloc buffer for communication */ envp->transBuf = calloc(1, envp->bufLen); assert(envp->transBuf); /* create socket */ listenSock = socket_tcp_server(envp->tcpPort, CAM_CTRL_LISTEN_NUM); if(listenSock < 0) { ERR("create server socket failed"); return E_IO; } /* set to non-blocking and use select for wait */ set_sock_block(listenSock, FALSE); /* create udp server socket */ udpScok = socket_udp_server(envp->udpPort); if(udpScok < 0) { ERR("create udp server socket failed"); return E_IO; } /* set timeout */ set_sock_send_timeout(udpScok, CAM_CTRL_TIMEOUT); set_sock_recv_timeout(udpScok, CAM_CTRL_TIMEOUT); udpProcEnv.cmdListenPort = envp->tcpPort; udpProcEnv.needReboot = FALSE; /* create icam ctrl handle */ envp->hCamCtrl = icam_ctrl_create(CAM_CTRL_MSG, 0, CAM_CTRL_TIMEOUT); if(!envp->hCamCtrl) { ERR("create cam ctrl handle failed"); ret = E_IO; goto quit; } /* init mutex for sync */ pthread_mutex_init(&envp->mutex, NULL); /* ignore signal when socket is closed by server */ signal(SIGPIPE, SIG_IGN); DBG("%s, port %u waiting for connection...", PROGRAM_NAME, envp->tcpPort); /* choose max fd */ fdMax = MAX(listenSock, udpScok) + 1; while(!exit) { /* wait data ready */ FD_ZERO(&rdSet); FD_SET(listenSock, &rdSet); FD_SET(udpScok, &rdSet); ret = select(fdMax, &rdSet, NULL, NULL, NULL); if(ret < 0 && errno != EINTR) { ERRSTR("select err"); break; } /* no data ready */ if(!ret) continue; /* check which is ready */ if(FD_ISSET(listenSock, &rdSet)){ /* accept connection */ tcp_accept(envp, listenSock); } if(FD_ISSET(udpScok, &rdSet)){ /* process udp cmd */ udp_process(udpScok, &udpProcEnv); if(udpProcEnv.needReboot) break; } } quit: if(listenSock > 0) close(listenSock); if(envp->hCamCtrl) icam_ctrl_delete(envp->hCamCtrl); pthread_mutex_destroy(&envp->mutex); free(envp->transBuf); if(udpProcEnv.needReboot) system("shutdown -r now\n"); return ret; }
static void main_loop(const char *serverIp, Uint16 port) { int sockTcp = socket_tcp_server(56790, 5); assert(sockTcp >= 0); int sockUdp = socket_udp_server(56790); assert(sockUdp >= 0); int err = set_sock_send_timeout(sockTcp, 5); err |= set_sock_recv_timeout(sockTcp, 5); assert(err == 0); err = set_sock_buf_size(sockUdp, 512 * 1024, 512 * 1024); err |= set_sock_linger(sockUdp, TRUE, 2); err |= set_sock_block(sockUdp, FALSE); DBG("err = %d", err); assert(err == 0); close(sockTcp); close(sockUdp); sockTcp = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in addr; init_sock_addr(&addr, serverIp, port); err = connect_nonblock(sockTcp, (struct sockaddr *)&addr, sizeof(addr), 5000); if(err < 0) { ERR("Connect nonblocking server failed."); goto exit; } else { DBG("Connect to %s:%u success!", serverIp, port); } close(sockTcp); close(sockUdp); sockTcp = sockUdp = -1; sockTcp = socket(AF_INET, SOCK_STREAM, 0); err = connect(sockTcp, (struct sockaddr *)&addr, sizeof(addr)); if(err < 0) { ERR("Connect server failed."); goto exit; } else { DBG("Connect to %s:%u success!", serverIp, port); } sockUdp = socket(AF_INET, SOCK_DGRAM, 0); char *sendLine = "Hello"; err = sendto(sockUdp, sendLine, strlen(sendLine), 0, (struct sockaddr *)&addr, sizeof(addr)); if(err < 0) ERR("Send to failed."); else DBG("Sendto ok..."); char ipBuf[32]; err = get_local_ip(ipBuf, sizeof(ipBuf)); assert(err == E_NO); DBG("get local ip: %s", ipBuf); Uint8 macAddr[6]; err = sys_get_mac("eth0", macAddr, sizeof(macAddr)); assert(err == E_NO); DBG("get mac addr: %02X-%02X-%02X-%02X-%02X-%02X", macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]); exit: if(sockTcp > 0) close(sockTcp); if(sockUdp > 0) close(sockUdp); }