MMOServer

sockopt(C++)

이야기prog 2025. 4. 2. 17:56
#include "pch.h"
#include <thread>
#include <atomic>
#include <mutex>
#include <future>
#include "CorePch.h"
#include "ThreadManager.h"
#include "RefCounting.h"
#include "Memory.h"
#include "TypeCast.h"

#include <WinSock2.h>
#include <MSWSock.h>
#include <WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib")

void HandleError(const char* str) {
	int32 errCode = ::WSAGetLastError();
	cout << str << " erroCode: " << errCode << endl;
}
int main() {
	//윈도우 소켓 초기화
// 관련 정보가 wsaData에 채워짐
	WSADATA wsaData;
	if (::WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
		return 0;

	SOCKET serverSocket = ::socket(AF_INET, SOCK_STREAM, 0);
	if (serverSocket == INVALID_SOCKET) {
		return 0;
	}

	// SOL_SOCKET, SO_KEEPALIVE 주기적으로 소켓의 연결이 끊어지지 않았는지 확인(TCP)
	bool enable = true;
	int32 dataSize = sizeof(enable);
	::setsockopt(serverSocket, SOL_SOCKET, SO_KEEPALIVE, (char*)&enable, sizeof(enable));
	

	// socket close 시, 버퍼에 남아있는 데이터를 위해 기다리는 시간 설정
	linger linger;
	linger.l_onoff = 1;
	linger.l_linger = 5;
	::setsockopt(serverSocket, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger));

	// shutdown은 half-close로 예를들어서 SD_SEND는 데이터 send를 끊겠다. 의미
	::shutdown(serverSocket, SD_SEND);


	//::getsockop에서 SO_SNDBUF, SO_RCVBUF는 소켓의 sendbuffer와 recvbuffer의 크기를 알 수 있다.
	int32 sendBufSize;
	int32 sndBufLen = sizeof(sendBufSize);
	int32 recvBufSize;
	int32 rcvBufLen = sizeof(recvBufSize);

	::getsockopt(serverSocket, SOL_SOCKET, SO_SNDBUF, (char*)&sendBufSize, &sndBufLen);
	::getsockopt(serverSocket, SOL_SOCKET, SO_RCVBUF, (char*)&recvBufSize, &rcvBufLen);

	// SO_REUSEADDR
	// IP주소 및 포트 재사용
	{
		bool enable = true;
		::setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&enable, sizeof(enable));
	}

	//IPPROTO_TCP
	// TCP_NODELAY = nagle 알고리즘 작동 여부 (네트워크 게임에서는 반응성이 중요한대 nagle 알고리즘 사용시
	// 데이터가 쌓여야 데이터를 보내기 때문에 끄는게 좋음.)

	{
		bool enable = true;
		::setsockopt(serverSocket, IPPROTO_TCP, TCP_NODELAY, (char*)&enable, sizeof(enable));

	}
	
	

	::WSACleanup(); // 윈속 종료
	return 0;
}