int tcpclient_open(urg_tcpclient_t* cli, const char* ip_str, int port_num) { enum { Connect_timeout_second = 2 }; fd_set rmask, wmask; struct timeval tv = { Connect_timeout_second, 0 }; #if defined(URG_WINDOWS_OS) u_long flag; #else int flag; int sock_optval = -1; int sock_optval_size = sizeof(sock_optval); #endif int ret; cli->sock_desc = Invalid_desc; cli->pushed_back = -1; // no pushed back char. #if defined(URG_WINDOWS_OS) { static int is_initialized = 0; WORD wVersionRequested = 0x0202; WSADATA WSAData; int err; if (!is_initialized) { err = WSAStartup(wVersionRequested, &WSAData); if (err != 0) { return -1; } is_initialized = 1; } } #endif tcpclient_buffer_init(cli); cli->sock_addr_size = sizeof (struct sockaddr_in); if ((cli->sock_desc = (int)socket(AF_INET, SOCK_STREAM, 0)) < 0) { return -1; } memset((char*)&(cli->server_addr), 0, sizeof(cli->sock_addr_size)); cli->server_addr.sin_family = AF_INET; cli->server_addr.sin_port = htons(port_num); if (!strcmp(ip_str, "localhost")) { ip_str = "127.0.0.1"; } /* bind is not required, and port number is dynamic */ if ((cli->server_addr.sin_addr.s_addr = inet_addr(ip_str)) == INADDR_NONE) { return -1; } #if defined(URG_WINDOWS_OS) // Configures non-blocking mode flag = 1; ioctlsocket(cli->sock_desc, FIONBIO, &flag); if (connect(cli->sock_desc, (const struct sockaddr *)&(cli->server_addr), cli->sock_addr_size) == SOCKET_ERROR) { int error_number = WSAGetLastError(); if (error_number != WSAEWOULDBLOCK) { tcpclient_close(cli); return -1; } FD_ZERO(&rmask); FD_SET((SOCKET)cli->sock_desc, &rmask); wmask = rmask; ret = select((int)cli->sock_desc + 1, &rmask, &wmask, NULL, &tv); if (ret == 0) { // Operation timed out tcpclient_close(cli); return -2; } } // Returns to blocking mode set_block_mode(cli); #else // Configures non-blocking mode flag = fcntl(cli->sock_desc, F_GETFL, 0); fcntl(cli->sock_desc, F_SETFL, flag | O_NONBLOCK); if (connect(cli->sock_desc, (const struct sockaddr *)&(cli->server_addr), cli->sock_addr_size) < 0) { if (errno != EINPROGRESS) { tcpclient_close(cli); return -1; } // EINPROGRESS: a connection request was already received and not completed yet FD_ZERO(&rmask); FD_SET(cli->sock_desc, &rmask); wmask = rmask; ret = select(cli->sock_desc + 1, &rmask, &wmask, NULL, &tv); if (ret <= 0) { // Operation timed out tcpclient_close(cli); return -2; } if (getsockopt(cli->sock_desc, SOL_SOCKET, SO_ERROR, (int*)&sock_optval, (socklen_t*)&sock_optval_size) != 0) { // Connection failed tcpclient_close(cli); return -3; } if (sock_optval != 0) { // Connection failed tcpclient_close(cli); return -4; } // Returns to blocking mode set_block_mode(cli); } #endif return 0; }
int tcpclient_open(tcpclient_t* cli, const char* ip_str, int port_num) { enum { Connect_timeout_second = 2 }; fd_set rmask, wmask; struct timeval tv = { Connect_timeout_second, 0 }; int flag; int sock_optval = -1; int sock_optval_size = sizeof(sock_optval); int ret; cli->sock_desc = Invalid_desc; cli->pushed_back = -1; // no pushed back char. tcpclient_buffer_init(cli); cli->sock_addr_size = sizeof (struct sockaddr_in); if ((cli->sock_desc = (int)socket(AF_INET, SOCK_STREAM, 0)) < 0) { return -1; } memset((char*)&(cli->server_addr), 0, sizeof(cli->sock_addr_size)); cli->server_addr.sin_family = AF_INET; cli->server_addr.sin_port = htons(port_num); if (!strcmp(ip_str, "localhost")) { ip_str = "127.0.0.1"; } /* bind is not required, and port number is dynamic */ if ((cli->server_addr.sin_addr.s_addr = inet_addr(ip_str)) == INADDR_NONE) { return -1; } flag = fcntl(cli->sock_desc, F_GETFL, 0); fcntl(cli->sock_desc, F_SETFL, flag | O_NONBLOCK); //printf("cli->sock_desc: %d\n",cli->sock_desc); if (connect(cli->sock_desc, (const struct sockaddr *)&(cli->server_addr), cli->sock_addr_size) < 0) { if (errno != EINPROGRESS) { tcpclient_close(cli); return -1; } // EINPROGRESS: FD_ZERO(&rmask); FD_SET(cli->sock_desc, &rmask); wmask = rmask; ret = select(cli->sock_desc + 1, &rmask, &wmask, NULL, &tv); if (ret <= 0) { tcpclient_close(cli); return -2; } if (getsockopt(cli->sock_desc, SOL_SOCKET, SO_ERROR, (int*)&sock_optval, (socklen_t*)&sock_optval_size) != 0) { tcpclient_close(cli); return -3; } if (sock_optval != 0) { tcpclient_close(cli); return -4; } set_block_mode(cli); } //printf("connection ok!\n"); return 0; }