본문 바로가기

UNIX_LINUX_C_C++

비블럭킹 TCP 연결 예제

[출처] 비블럭킹 TCP 연결|작성자 장인정신

mz_nonblockconnect

비블럭킹 TCP 연결 #

  • Non-blocking 연결은 생각보다 유용한 부분이 많은것 같습니다. 일반 connect 를 수행하면 상대방이 연결을 받아주지 않으면 무한정(대략 30초에서 2분) 대기상태로 빠지게 되는 단점이 있으나 Non-blocking 으로 connect 를 시도하면 제가 원하는 시간뒤에 빠져나올수 있어서 좋겠지요.

예제 #


/* Code by JaeHyuk Cho <mailto:minzkn@infoeq.com> */static int __MZ_Poll__(int s_Socket, int s_Event, int s_TimeOut){ /* s_TimeOut < 0 : Blocking, s_TimeOut = 0 : Non blocking, s_TimeOut > 0 : Time block */ int s_Check; struct pollfd s_PollFD; if(s_TimeOut >= 0) {  s_PollFD.fd = s_Socket, s_PollFD.events = s_Event;  do{s_Check = poll((struct pollfd *)(&s_PollFD), 1u, s_TimeOut);}while(s_Check == (-1) && errno == EINTR);  if(s_Check > 0)  {   if((s_PollFD.revents & s_Event))s_Check = 1;   else   {    s_Check = 0;    if(s_PollFD.revents & POLLHUP)    {     fprintf(stdout, "__MZ_Poll__: [WARNING] HUNG UP poll !\n");    }   }  } } else s_Check = 1; return(s_Check);} /* (-1): Disconnect, 0: Time out, 1: Poll OK */int MZ_ConnectEx(int s_Socket, void *s_SocketAddress, int s_SocketAddressSize, int s_TimeOut){ int s_Return = 0, s_SocketError, s_Check; socklen_t s_SocketErrorSize; #ifdef WIN32   unsigned long s_Flags = 0lu; #else int s_Flags = 0; #endif if(s_Socket != (-1) && s_SocketAddress) {  if(s_SocketAddressSize <= 0)s_SocketAddressSize = sizeof(struct sockaddr_in);  if(s_TimeOut >= 0)  {   #ifdef WIN32     s_Flags = 1lu;   s_Check = ioctl(s_Socket, FIONBIO, &s_Flags);   #else   s_Flags = fcntl(s_Socket, F_GETFL);   s_Check = fcntl(s_Socket, F_SETFL, s_Flags | O_NONBLOCK);   #endif  }  else s_Check = 0;  if(s_Check == 0)  {   if(connect(s_Socket, (struct sockaddr *)s_SocketAddress, (socklen_t)s_SocketAddressSize) == 0)s_Return = 1;   else if(s_TimeOut > 0)   {    s_Check = __MZ_Poll__(s_Socket, POLLIN | POLLOUT, s_TimeOut);    if(s_Check == 1)    {     s_SocketErrorSize = (socklen_t)sizeof(s_SocketError);     if(getsockopt(s_Socket, SOL_SOCKET, SO_ERROR, (void *)(&s_SocketError), (socklen_t *)(&s_SocketErrorSize)) == 0)     {      if(s_SocketError == 0)s_Return = 1;     }    }   }  }  if(s_TimeOut >= 0)  {   #ifdef WIN32     s_Flags = 0lu;   s_Check = ioctl(s_Socket, FIONBIO, &s_Flags);   #else   (void)fcntl(s_Socket, F_SETFL, s_Flags);   #endif  } } return(s_Return);}/* End of source */

대문 / 유용한 소스모음 / Nonblocking connection