#include "stdafx.h" #include "NetString.h" CNetString::CNetString(void) { m_iIndex = 0; m_hWnd = NULL; // ºÎ¸ð À©µµ¿ì ÇÚµé m_hSocket = NULL; // Ŭ¶óÀÌ¾ðÆ® ¼ÒÄÏ m_nPort = 0; // Æ÷Æ® ZeroMemory(m_strIPAddr, sizeof(char)*20); // Server IPÀúÀå m_bConnect = FALSE; // Á¢¼Ó »óÅ Ç÷¡±× m_bClose = FALSE; m_RecvIO.NewIOBuf(0); // 0À¸·Î ÇÏ¸é ±âº»ÀûÀ¸·Î DefaultPacketSize * 1024 m_hEvent = NULL; // ³×Æ®¿öÅ© À̺¥Æ® Çڵ鷯 ZeroMemory(m_PacketBuffer, sizeof(char)*MAX_PACKETSIZE); // Server IPÀúÀå WinSockInit(); } CNetString::~CNetString(void) { OnClose(); Stop(); // Á¾·á ÇÔ¼ö È£Ãâ m_RecvIO.DeleteIOBuf(); WSACleanup(); } BOOL CNetString::WinSockInit() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { WSACleanup(); // Tell the user that we could not find a usable // WinSock DLL. return FALSE; } if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { // Tell the user that we could not find a usable // // WinSock DLL. // WSACleanup( ); return FALSE; } return TRUE; } ////////////////////////////////////////////////////////////////// // [1]DESCRIPTION : Ŭ·¡½º ÃʱâÈ­ // // [2]PARAMETER : strIPAddr - ¿¬°áIPÁÖ¼Ò, nPort - Æ÷Æ®¹øÈ£, // // hWnd - ºÎ¸ð À©µµ¿ì ÇÚµé // // [3]RETURN : Á¤»ó - TRUE, ½ÇÆÐ - FALSE // // [4]DATE : 2000³â 9¿ù 11ÀÏ // ////////////////////////////////////////////////////////////////// BOOL CNetString::Init( HWND hWnd, int iIndex, char* szIP, int nPort ) { m_iIndex = iIndex; m_nPort = nPort; // Æ÷Æ® ¹øÈ£ unsigned long dwThreadId = 0; // ½º·¹µå »ý¼ºÀ» À§ÇÑ º¯¼ö // ip ¾îµå·¹½º strcpy(m_strIPAddr,szIP); m_hWnd = hWnd; // ºÎ¸ð ÇÚµé // ¿¬°áÀ» ½ÃŲ´Ù. ¼­¹ö·Î.. ¸¸¾à ¼­¹ö¿¬°á¿¡ ½ÇÆÐÇÑ´Ù¸é // Netword Event ¿¡¼­ FW_CLOSE°¡ ¹ß»ýÇØ ¼ÒÄÏÀÌ CloseµÈ´Ù. if(!Connect()) { // ½ÇÆÐÇßÀ»°æ¿ì Á¾·áÇÑ´Ù. Sleep(100); // Sleep... OnClose(); return FALSE; } m_bClose = FALSE; m_hEventThread = (HANDLE)CreateThread(NULL, // Security 0, // Stack size - use default EventThreadProc, // Thread fn entry point (void*) this, 0, // Init flag &dwThreadId); // Thread address return TRUE; } ////////////////////////////////////////////////////////////////// // [1]DESCRIPTION : Main Thread, ³×Æ®¿öÅ© À̺¥Æ® ó¸® // // [2]PARAMETER : void // // [3]RETURN : void // // [4]DATE : 2000³â 9¿ù 10ÀÏ // ////////////////////////////////////////////////////////////////// DWORD WINAPI CNetString::EventThreadProc(LPVOID lParam) { // Ŭ·¡½º¸¦ º¯¼ö·Î ¹ÞÀ½ CNetString* pThis = reinterpret_cast(lParam); WSANETWORKEVENTS events; // ³×Æ®¿öÅ© À̺¥Æ® º¯¼ö BOOL bThreadRun = TRUE; // ¹«ÇÑ ·çÇÁ º¯¼ö // ½º·¹µå ¹«ÇÑ ·çÇÁ while(bThreadRun) { if(pThis->m_bClose) { bThreadRun = FALSE; break; } DWORD dwRet; dwRet = WSAWaitForMultipleEvents(1, &pThis->m_hEvent, FALSE, INFINITE, FALSE); if(!pThis->m_hSocket) { // Á¾·á bThreadRun = FALSE; break; } // Figure out what happened int nRet = WSAEnumNetworkEvents(pThis->m_hSocket, pThis->m_hEvent, &events); // ¼ÒÄÏ ¿¡·¯¶ó¸é, if (nRet == SOCKET_ERROR) { bThreadRun = FALSE; break; } /////////////////// // Handle events // bThreadRun = pThis->NetworkEventHanlder(events.lNetworkEvents); } // À̸®·Î ½º·¹µå°¡ Á¾·á µÇ¸é Server¿¡ ÀÇÇÑ Å¬¶óÀÌ¾ðÆ® Á¾·á!!! <ºñÁ¤»ó Á¾·á> // ½º·¹µå ÃʱâÈ­´Â À§¿¡¼­ ÇØÁֱ⠶§¹®¿¡ ¿©±â¼­ ÇÏÁö´Â ¾Ê´Â´Ù. // pThis->CloseAll(); return 0; } void CNetString::Disconnect() { // ÀÌ°Ç ¹«Á¶°Ç CloseÇØÁà¾ßÇϱ⠶§¹®¿¡ CloseAll() È£ÃâÇÏÁö ¾Ê°í Á÷Á¢ ²ö´Ù. OnClose(); Stop(); // Á¾·á ÇÔ¼ö È£Ãâ } void CNetString::Stop() { if (m_hSocket) { struct linger li = {0, 0}; // Default: SO_DONTLINGER li.l_onoff = 1; // SO_LINGER, timeout = 0 shutdown(m_hSocket, SD_BOTH ); // ¿ÀÀ×? ÀÌ°Ô ¹¹Áö? ^^;; ´ã¿¡ ã¾Æº¸ÀÚ // 2001³â 9¿ù 6ÀÏ // Ŭ·ÎÁî ¼ÒÄÏ Àü¿¡ Å¥µÈ µ¥ÀÌŸ¸¦ º¸³¾Áö ¸»Áö °áÁ¤ÇÏ´Â ¿É¼Ç setsockopt(m_hSocket, SOL_SOCKET, SO_LINGER, (CHAR *)&li, sizeof(li)); closesocket(m_hSocket); // ¼ÒÄÏ ´Ý±â m_hSocket = NULL; } if(m_hEvent) WSACloseEvent(m_hEvent); m_hEvent = NULL; } void CNetString::CloseAll() { if(m_bConnect) { OnClose(); Stop(); // Á¾·á ÇÔ¼ö È£Ãâ } } BOOL CNetString::OnClose() { m_bClose = TRUE; m_bConnect = FALSE; // Connect º¯¼ö º¯°æ OnSocketEvent(WM_SOCK_CLOSE, 0); return FALSE; } ////////////////////////////////////////////////////////////////// // [1]DESCRIPTION : ¼­¹ö ¿¬°áÀ» À§ÇÑ ÇÔ¼ö // // [2]PARAMETER : void // // [3]RETURN : Á¤»ó - TRUE, ½ÇÆÐ - FALSE // // [4]DATE : 2000³â 9¿ù 11ÀÏ // ////////////////////////////////////////////////////////////////// BOOL CNetString::Connect() { // ¿¬°áÁßÀ̶ó¸é if(m_bConnect) return TRUE; // ¼ÒÄÏÀÌ ³²¾Æ ÀÖ´Ù¸é Stop(); m_RecvIO.InitIOBuf(); // ¼ÒÄÏ »ý¼º m_hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // ¼ÒÄÏ »ý¼º °Ë»ç if (m_hSocket == INVALID_SOCKET) { OnSocketEvent(WM_CONNECT, FALSE); return FALSE; } // ³×Æ®¿öÅ© À̺¥Æ® ÇÚµé »ý¼º m_hEvent = WSACreateEvent(); if (m_hEvent == WSA_INVALID_EVENT) { Stop(); return FALSE; } // Request async notification int nRet = WSAEventSelect(m_hSocket, m_hEvent, FD_CLOSE | FD_CONNECT); // ½ÅÈ£¸¦ ¼±º°ÇÏ¿© ¹Þ°Ô ÇÑ´Ù // ¿¡·¯¶ó¸é if (nRet == SOCKET_ERROR) { Stop(); return FALSE; } // ºñµ¿±â ¹æ½Ä unsigned long ul = 1; nRet = ioctlsocket(m_hSocket, FIONBIO, (unsigned long*)&ul); // ¼ÒÄÏ »ý¼º °Ë»ç if (m_hSocket == SOCKET_ERROR) { OnSocketEvent(WM_CONNECT, FALSE); return FALSE; } ///////////////////////////////// // ¼ÒÄÏÀÇ ¼º´É ÃÖÀûÈ­¸¦ À§ÇÑ ¼¼ÆÃ int zero = 0; int err = 0; // Send Buffer¿¡ ´ëÇÑ ¼¼ÆÃ if( (err = setsockopt( m_hSocket, SOL_SOCKET, SO_SNDBUF, (const char*)&zero, sizeof(zero))) == SOCKET_ERROR) { closesocket(m_hSocket); m_hSocket = NULL; return FALSE; } // Receive Buffer¿¡ ´ëÇÑ ¼¼ÆÃ if((err = setsockopt( m_hSocket, SOL_SOCKET, SO_RCVBUF, (const char*)&zero, sizeof(zero) )) == SOCKET_ERROR) { closesocket(m_hSocket); m_hSocket = NULL; return FALSE; } SOCKADDR_IN saServer; memset(&saServer,0,sizeof(saServer)); saServer.sin_family = AF_INET; saServer.sin_addr.s_addr = inet_addr(m_strIPAddr); saServer.sin_port = htons(m_nPort); // ¼­¹ö¿Í Connect nRet = connect(m_hSocket,(sockaddr*)&saServer, sizeof(saServer)); // ¼ÒÄÏ ¿¡·¯À̰ųª ºí·°Å·ÀÌ µÇ¾ú´Ù¸é if (nRet == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK) { Stop(); return FALSE; } /* ÀÌ·¸°Ô Connect¸¦ ÇÏ¸é ¼­¹ö´Â AccetpEx°¡ ¼º°øÇÏ¿© ClientSceesionÀº Recv´ë±â»óÅ·Πµé¾î°£´Ù. ¼ÒÄÏ À̺¥Æ®´Â Connect°¡ ¼º°øÇϸé FD_CONNECT¸¦ ¹ß»ý½ÃŲ´Ù. */ return TRUE; } ////////////////////////////////////////////////////////////////// // [1]DESCRIPTION : ³×Æ®¿öÅ© ¸Þ¼¼Áö¸¦ Çڵ鸵 ÇÏ¿© ºÐ±â // // [2]PARAMETER : lEvent - À̺¥Æ® // // [3]RETURN : void // // [4]DATE : 2000³â 9¿ù 14ÀÏ // ////////////////////////////////////////////////////////////////// BOOL CNetString::NetworkEventHanlder(LONG lEvent) { BOOL bFlag = TRUE; if(lEvent & FD_CLOSE) { bFlag = FALSE; } if(lEvent & FD_CONNECT) { bFlag = OnConnect(); } return bFlag; } void CNetString::Update() { if(!IsConnect()) return; OnSendPacketData(); OnReadPacketData(); while(GetQueCnt() != 0) { int iCnt = GetPacket(m_PacketBuffer); ProcessPacket(m_PacketBuffer, iCnt); // printf(m_PacketBuffer); PopPacket(); } } void CNetString::ProcessPacket(char* Packet, int PacketLen) { if(m_event) m_event->EventPacket(m_iIndex, Packet); } void CNetString::SendPost(char* Packet) { // ¼­¹ö·Î Send Çϱâ.. m_SendQue.push_back(Packet); } void CNetString::OnSendPacketData() { if(m_SendQue.empty()) return; ////////////////////////////////////////////////////////////////////////////// // Send int rc = 0; int idx = 0,size = 0; char send_buf[MAX_PACKETSIZE]; strcpy(send_buf, m_SendQue.begin()->c_str()); size = (int)strlen(send_buf); while(size > 0) { // 10004 : WSACancelBlockingCall¸¦ È£ÃâÇÏ¿© Â÷´Ü ÀÛ¾÷ÀÌ ÁߴܵǾú½À´Ï´Ù. // 10058 : ÇØ´ç ¼ÒÄÏÀÌ Á¾·áµÇ¾úÀ¸¹Ç·Î µ¥ÀÌÅÍ º¸³»°Å³ª ¹ÞÀ» ¼ö ¾ø½À´Ï´Ù. // 10038 : ¿¬°áÀÌ ²÷¾îÁø ¼ÒÄÏÀ» »ç¿ëÇÒ·Á°í ÇÒ¶§ ³­´Ù. if((rc = send(m_hSocket, &send_buf[idx], size, 0)) == SOCKET_ERROR) { // ºí·°Å· ¿¡·¯¶ó¸é if (GetLastError() != WSAEWOULDBLOCK) // ºí·°Å· ¿¡·¯°¡ ¾Æ´Ï¶ó¸é { break; } } else { // ¿¡·¯°¡ ¾ø´Ù¸é size -= rc; idx += rc; } m_SendQue.pop_front(); } } void CNetString::OnReadPacketData() { ////////////////////////////////////////////////////////////////////////////// // Recv int Ret = recv(m_hSocket, m_PacketBuffer, MAX_PACKETSIZE, 0); // µ¥ÀÌŸ Receive if(Ret == 0) // Graceful close { CloseAll(); return; } else if (Ret == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK ) // ºí·°Å· ¿¡·¯°¡ ¾Æ´Ï¶ó¸é { m_bConnect = FALSE; Stop(); // ÇÁ·Î±×·¥ Á¾·á return; } if(Ret > 0) { if(m_RecvIO.Append(m_PacketBuffer, Ret) == -1) { ; } } // ¹ÞÀº ÆÐŶÀº IOBuffer¿¡ ³Ö¾î ó¸®ÇÑ´Ù. int iLen = m_RecvIO.GetPacket(m_PacketBuffer); if(iLen > 0) { // ¿©±â¼­ ÇÑÆÐŶ ó¸® ·çƾ È£Ãâ m_RecvQue.push_back(m_PacketBuffer); // Message Type À϶§ À̰ɷΠº¸³½´Ù. // ¸¸¾à Update À̺¥Æ® È£ÃâÀ̸é ÀÌ ·çƾÀ» ÁÖ¼®Ã³¸® ÇØÁØ´Ù. OnSocketEvent(WM_RECV_MSG, iLen); } } ////////////////////////////////////////////////////////////////// // [1]DESCRIPTION : À̺¥Æ® ó¸® (On Connect) // // [2]PARAMETER : void // // [3]RETURN : false ¹Ýȯ // // [4]DATE : 2000³â 9¿ù 11ÀÏ // ////////////////////////////////////////////////////////////////// BOOL CNetString::OnConnect() { m_bConnect = TRUE; // ¿¬°á º¯¼ö ¼³Á¤ ON OnSocketEvent(WM_CONNECT, m_bConnect); return m_bConnect; } void CNetString::SetParent(HWND hWnd) { m_hWnd = hWnd; } void CNetString::GetLocalIP(char* LocalIP) { char name[256]; char* TempIp; PHOSTENT hostinfo; WinSockInit(); if( gethostname ( name, sizeof(name)) == 0) { if((hostinfo = gethostbyname(name)) != NULL) { TempIp = inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list); strcpy(LocalIP, TempIp); } } }