Operation now in progress 이란 message에 대한 대처
Timeout이 지원되는 TCP Connection을 구현해 보았습니다.
그런데 Error가발생하여 찍어보니, "Operation now in progress" 라고 나오네요.
어떻게 대처해야 하는지요. 또 왜 이런 메시지가 나오는지 궁금합니다.
코드 첨부합니다.
아래 코드중 getsockopt부분에서 ret값이 0보다 커서 cout
살펴봐주세요.
P.S. 코드를 삽입할때 다른방법이 있는 것 같은데, 몰라서 그냥 쭉 긁어넣습니다. 죄송합니다.
int32 TCPConnect(string strHostName, int32 nPort, int32 nTimeoutSec)
{
// DebugMessage("CNetworkClient::TCPConnect-->");
// DebugMessage((char*)strHostName.c_str());
// DebugMessage("\n");
//Domain Name resolution
string strIPAddress;
if(NameResolution(strHostName, strIPAddress) != NWC_OK){
DebugMessage("CNetworkClient::TCPConnect-->NameResolution fail\n");
return NWC_TCP_CONNECTION_ERROR;
}
//TCP Connect
int32 socketFD;
int32 err;
int32 saveFlags,ret,back_err;
fd_set fd_w;
struct timeval timeout;
struct sockaddr_in sockAddr;
/*connects to server
*/
socketFD = socket(AF_INET, SOCK_STREAM,0);
memset(&sockAddr,'\0', sizeof(sockAddr));
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(nPort);
sockAddr.sin_addr.s_addr = inet_addr(strIPAddress.c_str());
// inet_pton(AF_INET, strIpAddress, &sockAddr.sin_addr);
DebugMessage("CNetworkClient::TCPConnect-->Try to Connect host~");
DebugMessage((char*)strHostName.c_str());DebugMessage("\n");
saveFlags = fcntl(socketFD, F_GETFL, 0);
if(saveFlags
{
DebugMessage("CNetworkClient::TCPConnect-->fcntl()1 error\n");
return NWC_ERROR;
}
//Set Non Blocking
if(fcntl(socketFD, F_SETFL, saveFlags | O_NONBLOCK)
{
DebugMessage("CNetworkClient::TCPConnect-->fcntl()2 error\n");
return NWC_ERROR;
}
err=connect(socketFD, (struct sockaddr*)&sockAddr, sizeof(sockAddr));
back_err = errno;
//resotre flags
if(fcntl(socketFD, F_SETFL, saveFlags)
{
DebugMessage("CNetworkClient::TCPConnect-->fcntl()3 error\n");
return NWC_ERROR;
}
/* return unless the connection was successful or the connect is
still in progress. */
if(err
{
DebugMessage("CNetworkClient::TCPConnect-->connect() error\n");
return NWC_ERROR;
}
timeout.tv_sec = (long)nTimeoutSec;
timeout.tv_usec = 0L;
FD_ZERO(&fd_w);
FD_SET(socketFD,&fd_w);
err=select(FD_SETSIZE,NULL,&fd_w,NULL,&timeout);
if(err
{
DebugMessage("CNetworkClient::TCPConnect-->select() error\n");
return NWC_ERROR;
}
/* 0 means it timeout out & no fds changed */
if(err==0)
{
DebugMessage("CNetworkClient::TCPConnect-->Timeout Occured\n");
return NWC_ERROR;
}
// Get the return code from the connect
socklen_t len=sizeof(ret);
err=getsockopt(socketFD,SOL_SOCKET,SO_ERROR,&ret,&len);
if(err
{
DebugMessage("CNetworkClient::TCPConnect-->getsockopt() error\n");
return NWC_ERROR;
}
// ret=0 means success, otherwise it contains the errno
if(ret)
{
err=ret;
cout
return NWC_ERROR;
}
if(m_nTCPSocketFD !=-1){
// cout
close(m_nTCPSocketFD);
}
m_nTCPSocketFD = socketFD;
// cout
return NWC_OK;
}
대체로는 -1을
대체로는 -1을 리턴하면 에러이지만, 위처럼 논블록킹으로 세팅한 경우에는 에러가 아닐 수 있습니다. 항상 errno를 검토해야 합니다.
보통의 시스템호출은 (예를 들어, connect()) 하는만큼해보고(상당히 문학적...--; ) 안되면 에러를 리턴합니다만
, 논블록킹으로 세팅한 소켓에 대해, 시스템호출(connect() )은 해당 시스템호출을 완료하기 전에(소위 해보기도 전에....이또한 상당히 문학적.....) 일단 리턴하므로 - 왜냐면 논블록킹이니까 - 이 경우에는 -1을 리턴해도 에러라고 단정할 수 없습니다.
이경우 에러메시지는 " 현재 진행중... 하고 있다... 아직 다 안했다..." 라는 메시지를 보내게 됩니다. 질문처럼 오퍼레이션이 진행중이라던지.. 모 이렇게 말입니다.
이에 따른 적절한 처리만 해주시면 되겠습니다.
* 논 블록킹 프로그래밍은 프로그래머에게는 다소 귀찮지만(버퍼관리, 연결관리 등등땜시) , 해보면 재미 또한 있습니다.
댓글 달기