//------------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <netdb.h>
#include <fcntl.h>
//------------------------------------------------------------------------------
int SocketConnect(char *sHostIp, char *sServicePort, int nTimeout)
{
int nRet = -1;
int nRealPort = -1;
int nSockFd = -1;
struct sockaddr_in name;
struct hostent *hp;
struct servent *sp;
nSockFd = socket (AF_INET, SOCK_STREAM, 0);
if ( nSockFd < 0 ) {
fprintf(stderr, "socket open error : %d[%s]\n", errno, strerror(errno) ); fflush(stderr);
return -1;
}
if ( !isdigit(sServicePort[0]) ) { /* 숫자값이 아닐경우 즉 서비스명으로 되어 있을 경우 만약 서비스명의 맨앞이 숫자로 되어있는경우 구분이 안되는 문제가 생기게됨.*/
sp = getservbyname ( sServicePort, "tcp");
if ( sp == NULL ) {
fprintf(stderr, "getservbyname error : [%s]\n", sServicePort);
return -1;
}
else {
nRealPort = sp->s_port;
}
}
else { /* 숫자값으로 되어 있을 경우 즉 PORT번호로 되어 있을 경우 */
nRealPort = atoi(sServicePort);
}
if( nRealPort <= 0 ) {
fprintf(stderr, "Invalid RealPort error : [%d]\n", nRealPort);
return -1;
}
if ( !isdigit(sHostIp[0]) ) { /* 숫자가 아닌 HOST명으로 되어 있을 경우 호스트명의 맨앞이 숫자로되어 있을 경우 구분이 안되는 문제가 생길수 있음 */
hp = gethostbyname (sHostIp);
if ( hp == NULL ) {
fprintf(stderr, "gethostbyname error :[%s]\n", sHostIp);
return -1;
}
memcpy ( (char *)&name.sin_addr, hp->h_addr_list[0], hp->h_length );
name.sin_family = hp->h_addrtype;
}
else { /* 숫자값 즉 IP로 되어 있을 경우 */
name.sin_addr.s_addr = inet_addr (sHostIp);
name.sin_family = AF_INET;
}
name.sin_port = ntohs(nRealPort);
nRet = ConnectTimeout( nSockFd, (struct sockaddr *)&name, sizeof(name), nTimeout );
if( nRet < 0 ) {
fprintf(stderr, "ConnectTimeout error : nRet[%d][%d][%s]\n", nRet, errno, strerror(errno));
return -1;
}
return nSockFd;
}
//------------------------------------------------------------------------------
int ConnectTimeout(int sfd, struct sockaddr *serv_addr, socklen_t addrlen, int timeout)
{
int nRet, slen, flags;
struct timeval tv;
struct sockaddr_in addr;
fd_set rdf, wrf;
flags = fcntl(sfd, F_GETFL, 0);
fcntl(sfd, F_SETFL, flags | O_NONBLOCK);
nRet = connect(sfd, serv_addr, addrlen);
if (nRet >= 0) { /* connect completed immediately */
return nRet ;
}
else {
if (errno != EINPROGRESS) { /* 에러이면서 connect 처리중인 상태가 아닐경우 */
close(sfd);
return (-1);
}
}
FD_ZERO(&rdf);
FD_ZERO(&wrf);
FD_SET(sfd, &rdf);
FD_SET(sfd, &wrf);
bzero(&tv, sizeof(tv));
tv.tv_sec = timeout;
tv.tv_usec = 0;
if (select(sfd + 1, &rdf, &wrf, 0, &tv) <= 0) { /* timeout */
close(sfd);
errno = ETIMEDOUT;
return (-1);
}
if ( FD_ISSET(sfd, &wrf) || FD_ISSET(sfd, &rdf) ) {
slen = sizeof(addr);
if (getpeername(sfd, (struct sockaddr*)&addr, &slen) == -1) {
close(sfd);
return (-1);
}
flags = fcntl(sfd, F_GETFL, 0);
fcntl(sfd, F_SETFL, flags & ~O_NONBLOCK);
return 0;
}
else {
close(sfd);
return (-1);
}
}
//------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
int nSockFd = -1;
char sHostIp[30];
char sServicePort[30];
int nTimeout = 3;
if( argc != 3 ) {
fprintf(stdout, "USAGE : %s [HOST | IP] [SERVICE | PORT] \n", argv[0]);
exit(0);
}
memset(sHostIp, 0x00, sizeof(sHostIp));
sprintf(sHostIp, "%s", argv[1]);
memset(sServicePort, 0x00, sizeof(sServicePort));
sprintf(sServicePort, "%s", argv[2]);
nSockFd = SocketConnect(sHostIp, sServicePort, nTimeout);
if( nSockFd < 0 ) {
fprintf(stderr, "SocketConnect fail \n");
return 0;
}
fprintf(stdout, "SocketConnect Ok \n");
/** socket send / socket recv **/
close(nSockFd);
}
//------------------------------------------------------------------------------