비정상 종료로 인하여 고스트 세션이 발생하였을 때 처리 방법으론 자체적으로 HeartBeat를 만들어 주기적으로 Send를 하거나
소켓 옵션을 통하여 처리하면 된다.
window 서버 2010 이상, Window 8.1 이상 지원
C# => IOControl
WinSock => WSAIoctl을 사용하면 된다.
소켓을 IOCP에 물렸을 경우 GetQueuedCompletionStatus()에서 False와 ERROR_SEM_TIMEOUT Error로 떨어짐.
C#
public class TcpKeepAlive
{
public uint OnOff { get; set; }
public uint KeepAliveTime { get; set; }
public uint KeepAliveInterval { get; set; }
public byte[] GetBytes()
{
return BitConverter.GetBytes(OnOff).Concat(BitConverter.GetBytes(KeepAliveTime)).Concat(BitConverter.GetBytes(KeepAliveInterval)).ToArray();
}
}
var option = new TcpKeepAlive
{
OnOff = 1,
KeepAliveTime = 5000,
KeepAliveInterval = 1000
};
state.Socket.IOControl(IOControlCode.KeepAliveValues, option.GetBytes(), null);
C++
#include <mstcpip.h>
tcp_keepalive keepAlive;
keepAlive.onoff = 1;
keepAlive.keepalivetime = 5000;
keepAlive.keepaliveinterval = 1000;
DWORD option;
WSAIoctl(stateObject->Socket(), SIO_KEEPALIVE_VALS, &keepAlive, sizeof(keepAlive), 0, 0, &option, NULL, NULL);
if (!GetQueuedCompletionStatus(_completionPort, &bytesTrans, &stateObject, (LPOVERLAPPED *)&overlapped, INFINITE))
{
int error = WSAGetLastError();
printf("Error : %d\n", error);
auto pHandler = reinterpret_cast<StateObject*>(stateObject);
switch (error)
{
case ERROR_SEM_TIMEOUT:
case ERROR_NETNAME_DELETED:
ClosePeer(pHandler);
default:
break;
}
continue;
}
'개발관련 > C#' 카테고리의 다른 글
Thread Synchronization spinlock vs lock performance (0) | 2022.12.20 |
---|---|
.net core 패킷 데이터가 30K 바이트보다 큰 경우 디스크에 저장 (0) | 2022.04.06 |
C++/CLI를 통한 C++ 클래스 마샬링 (0) | 2018.08.11 |
sql compact 4.0 설정 (2) | 2018.07.30 |
SignalR MessageFormat 및 구동 시퀸스 (0) | 2018.07.14 |