setsockopt(IN SOCKET socket, IN int name, IN int optlevel, IN const char* optvalue, IN int optlen);
[1] 입출력 버퍼크기의 변경
SOCKET sock = socket(PF_INET, SOCK_STREAM, 0);
int send_buf = 500;
int rcv_buf = 1000;
int state = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char*)&rcv_buf, sizeof(rcv_buf));
if(state) errorhandling("setsockopt() error");
state = setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char*)&send_buf, sizeof(send_buf));
if(state) errorhandling("setsockopt() error");
|
[2] Nagle 알고리즘의 적용 - 한번에 모아서 전송
TCP 소켓은 기본적으로 Nagle 알고림을 사용하여 한번에 모아서 전송함. 지연 발생(100~200ms).
이 옵션 사용시 리턴과 동시에 데이터 전송이 이루어지나 회선 부하가 많아짐.
int sock;
int flag = 1; // 네이글 알고리즘 off
sock = open(...);
if ( setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int)) < 0)
{
printf("setsockopt error\n");
....
}
|
[3] 송/수신 TIMEOUT 설정 - 블러킹 소켓일 경우
SCOKET hSocket;
int nErrorCode;
hSocket = socket(AF_INET,SOCK_STREAM,0);
~~~~
nErrorCode = connect(~~~~~~);
~~~
// RECEIVE & SEND TIMEOUT 설정법
// hSocket이 블럭킹상태(Blocking) 일경우 해당된다. 논 블럭킹 상태(None-Blocking) 이면 recv에서 SOCKET_ERROR를 반환하고
//WSAGetLastError()로 확인 하면 WSAEWOULDBLOCK를 반환 한다.
//WSAEWOULDBLOCK이 에러가 아니고, 다른 에러 이면 에러 코드를 참조 하여 에러 처리를 한다.
// Receive Time Out Value : 3000 (약 3초)
int nTimeOutValue = 3000;
nErrorCode = setsockopt(hSocket, SOL_SOCKET, SO_RCVTIMEO,(const char*)&nTimeOutValue,sizeof(nTimeOutValue));
if(SOCKET_ERROR == nErrorCode){ // 에러 처리
}
nErrorCode = setsockopt(hSocket, SOL_SOCKET, SO_SNDTIMEO,(const char*)&nTimeOutValue,sizeof(nTimeOutValue));
if(SOCKET_ERROR == nErrorCode) { // 에러 처리
}
nErrorCode = send(hSocket,버퍼,전송할 버퍼크기, 0);
~~~
nErrorCode = recv(hSocket,버퍼, 버퍼크기, 0);
~~~
|
[4] 소켓 종료시 종료방식 설정
LINGER 구조체의 _onoff _linger 두개의 값에 플래그를 지정하고 setsockopt 에 설정
l_onoff = 0, l_linger = 0(또는 1) : 버퍼에 있는 내용을 모두 전송후 연결 종료한다.
l_onoff = 1, l_linger = 0 : 즉시 연결을 종료한다. 상대방에게는 FIN이나 RTS 시그널이 전달된다.
l_linger = 1 : 버퍼에 있는 내용을 모두 전송후에 연결을 종료한다. 이 동안 closesocket 은 block 된다.
LINGER opt = {onoff, linger}; // 값을 설정
setsockopt(socket, SOL_SOCKET, SO_LINGER, (char *)&opt, sizeof(opt));
|
[5] 소켓 비정상 종료시 재 bind 를 허용하도록 함
bind 되었던 소켓이 서버의 비정상 종료로 커널이 아직 그 정보를 갖고 있을 경우, 다시금 bind 할 수 없는 경우가 있는데,
이때 선점된 주소로 인해 bind에 실패할 수 있다. 이 옵션은 재 bind 할 수 있도록 한다.
bool reuseflag = true;
setsockop(listen_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&reuseflag, sizeof(reuseflag));
|
[6] UDP 소켓을 브로드캐스트 가능하도록 설정
디폴트로 생성되는 UDP소켓은 브로드캐스트가 불가능하도록 설정되어있다. 이 소켓을 브로트캐스트가 가능하도록 한다.
// serverside
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr(szServerAddress);
serverAddr.sin_port = htons(nPort); // 포트는 serverside 와 clientside 모두 통일
state = setsockopt(hSock, SOL_SOCKET, SO_BROADCAST, (char *)&serverAddr, sizeof(serverAddr));
|