환경: C++ Builder XE5 (RADStudio XE5)
TServerSocket을 이용하여 여러 단말 Unit(H/W장비)과 통신 구현 중입니다.
단말에서는 서버와 통신이 되지 않으면 Ethernet Module을 껐다가 켜기 때문에(Delay Time 1분),
TServerSocket에서 Socket의 종료를 알수 없습니다.(Event가 발생하지 않음. 3-handshake-close 등의 소켓 종료가 안되는 상황)
그래서, Socket의 KeepAlive를 이용하여 Dead Socket을 강제적으로 정리하려고 하는데요..
아래와 같은 코드로 Socket의 옵션을 조정하려 합니다.
그런데, 아래와 같은 에러 코드가 보입니다.
[ilink32 Error] Error: Unresolved external 'WSAIoctl' referenced from D:\RMEASUREAWAC\TEST\BUILDER\TEST01\WIN32\DEBUG\UNITMAIN.OBJ
제가 작업한 것은 아래와 같습니다.
// Tools Option에 Library Path Add : ws2_32.lib 있는 폴더..Library Path에 추가
Tools => Options => Delphi Options => Library => Library Path 추가
- Selected Platform : 32-bit Windows
- C:\Program Files (x86)\Embarcadero\RAD Studio\12.0\lib\win32\release
- C:\Program Files (x86)\Embarcadero\RAD Studio\12.0\lib\win32\release\psdk
Tools => Options => C++ Options => Paths and Directories => Library Path 에 추가
- Selected Platform : 32-bit Windows
- C:\Program Files (x86)\Embarcadero\RAD Studio\12.0\lib\win32\release
- C:\Program Files (x86)\Embarcadero\RAD Studio\12.0\lib\win32\release\psdk
// Project Option 에 header file, library가 있는 곳 지정.
Project => Options 에서 두 개의 Path에 Winsock2 관련 폴더 추가
Include Path에 winsock2.h 이 있는 위치 추가
- C:\Program Files (x86)\Embarcadero\RAD Studio\12.0\include\windows\sdk
Libary Path에 ws2_32.lib 이 있는 위치 추가
- C:\Program Files (x86)\Embarcadero\RAD Studio\12.0\lib\win32\release
- C:\Program Files (x86)\Embarcadero\RAD Studio\12.0\lib\win32\release\psdk
소스 코드는 아래와 같습니다.
#include
#include
....
//---------------------------------------------------------------------------
void __fastcall TForm1::ServerSocket1Accept(TObject *Sender, TCustomWinSocket *Socket)
{
tcp_keepalive tcpkl;
tcpkl.onoff = 1;
tcpkl.keepalivetime = 20 * 1000; // 20초마다 keepalive신호를 보내겠다. (Default 2시간)
tcpkl.keepaliveinterval = 1 * 1000; // keepalive 신호를 보내고 응답이 없으면 1초마다 재전송하겠다.(ms tcp 10회 재시도-고정)
DWORD dwRet = 0;
int iResult = 0;
iResult = WSAIoctl(Socket->SocketHandle, SIO_KEEPALIVE_VALS, &tcpkl, sizeof(tcp_keepalive), 0, 0, &dwRet, NULL, NULL);
if ( iResult == 0 ) {
ShowMessage("WSAloctl .. ok..");
}
}
뭐가 잘못된 것인 지 고수님들의 도움을 요청합니다.
감사합니다.