공부

내 PC의 backlog 큐 개수 구하기

글로벌디노 2020. 10. 8. 13:44

내 PC의 backlog 큐 개수 구하기

 

20210731 수정

 

아이디 '백수'님의 조언을 참고해서 클라이언트 코드를 수정해서 다시 테스트 해 보았다

생각해보니 현재 테스트는 클라이언트의 연결이 유지될 필요가 없었다

 

connect() 후 closesocket()을 호출하도록 코드를 수정했다

TIME_WAIT 상태가 남지 않도록 링거옵션도 추가했다

 

 

클라이언트 코드

#pragma comment(lib, "Ws2_32.lib")
#include <WinSock2.h>
#include <ws2tcpip.h>
#include <stdio.h>

int main()
{
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
	{
		wprintf_s(L"WSAStartup() errcode[%d]\n", WSAGetLastError());
		return 1;
	}

	SOCKADDR_IN sockAddr;
	memset(&sockAddr, 0, sizeof(sockAddr));
	sockAddr.sin_family = AF_INET;
	sockAddr.sin_port = htons(7000);
	InetPtonW(AF_INET, L"127.0.0.1", &sockAddr.sin_addr);

	int conCount = 0;
	for (;;)
	{
		SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
		if (sock == INVALID_SOCKET)
		{
			wprintf_s(L"socket() errcode[%d]\n", WSAGetLastError());
			wprintf_s(L"socket create maxcount ( %d )\n", conCount);
			WSACleanup();
			return 1;
		}

		LINGER lin;
		lin.l_onoff = 1;
		lin.l_linger = 0;
		setsockopt(sock, SOL_SOCKET, SO_LINGER, (char*)&lin, sizeof(lin));

		if (connect(sock, (SOCKADDR*)&sockAddr, sizeof(sockAddr)) == SOCKET_ERROR)
		{
			wprintf_s(L"connect() errcode[%d]\n", WSAGetLastError());
			wprintf_s(L"socket create maxcount ( %d )\n", conCount);
			WSACleanup();
			return 1;
		}

		closesocket(sock);
		++conCount;
	}

	return 0;
}

 

SOMAXCONN_HINT(70000)

65535 개의 백로그큐 사이즈를 확인할 수 있었다

 

 

20210731 수정 끝


 

서버코드

#include <stdio.h>
#include <conio.h>
#include <WinSock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "Ws2_32.lib")

int main()
{
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
	{
		wprintf_s(L"WSAStartup() errcode[%d]\n", WSAGetLastError());
		return 1;
	}

	SOCKET listenSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (listenSock == INVALID_SOCKET)
	{
		wprintf_s(L"socket() errcode[%d]\n", WSAGetLastError());
		return 1;
	}

	SOCKADDR_IN servAddr;
	ZeroMemory(&servAddr, sizeof(servAddr));
	servAddr.sin_family = AF_INET;
	servAddr.sin_port = htons(7000);
	servAddr.sin_addr.s_addr = htonl(INADDR_ANY);

	int ret = bind(listenSock, (SOCKADDR*)&servAddr, sizeof(servAddr));
	if (ret == SOCKET_ERROR)
	{
		wprintf_s(L"bind() errcode[%d]\n", WSAGetLastError());
		return 1;
	}

	ret = listen(listenSock, 5);
	if (ret == SOCKET_ERROR)
	{
		wprintf_s(L"listen() errcode[%d]\n", WSAGetLastError());
		return 1;
	}

	while (1)
	{
		if (_kbhit())
		{
			int input = _getch();
			if (input == 'q')
				break;
		}
	}

	closesocket(listenSock);
	WSACleanup();

	return 0;
}

backlog 사이즈를 5로 설정한다

accept() 를 실행하지 않는다 ( backlog를 비우지 않는다 )

'q' 가 눌릴때까지 프로그램을 종료하지 않는다

 

 

클라이언트 코드

#include <stdio.h>
#include <conio.h>
#include <WinSock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "Ws2_32.lib")

#define MAXSOCKET 70000
SOCKET sockets[MAXSOCKET];

int main()
{
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
	{
		wprintf_s(L"WSAStartup() errcode[%d]\n", WSAGetLastError());
		return 1;
	}

	SOCKADDR_IN sockAddr;
	memset(&sockAddr, 0, sizeof(sockAddr));
	sockAddr.sin_family = AF_INET;
	sockAddr.sin_port = htons(7000);
	InetPtonW(AF_INET, L"127.0.0.1", &sockAddr.sin_addr);

	for (int i = 0; i < MAXSOCKET; i++)
	{
		sockets[i] = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
		if (sockets[i] == INVALID_SOCKET)
		{
			wprintf_s(L"socket() errcode[%d]\n", WSAGetLastError());
			wprintf_s(L"socket create maxcount ( %d )\n", i);
			return 1;
		}

		if (connect(sockets[i], (SOCKADDR*)&sockAddr, sizeof(sockAddr)) == SOCKET_ERROR)
		{
			wprintf_s(L"connect() errcode[%d]\n", WSAGetLastError());
			wprintf_s(L"socket create maxcount ( %d )\n", i);
			return 1;
		}
	}

	while (1)
	{
		if (_kbhit())
		{
			int input = _getch();
			if (input == 'q')
				break;
		}
	}

	for(int i = 0; i < MAXSOCKET; i++)
		closesocket(sockets[i]);

	WSACleanup();

	return 0;
}

70000번 소켓을 생성하고 connect 시도해본다

에러가 나는 이유와 소켓을 얼마나 생성하고 연결했는지 출력한다

 

 

서버실행 후 클라이언트 실행 결과

에러코드는 10061 (에러코드설명 MSDN)

소켓은 서버에서 설정한 backlogQ 사이즈인 5개까지 생성 및 연결이 되었다

 

cmd 창에서 netstat -an 실행

 

backlogQ 사이즈를 1000 으로 설정하고 테스트

소켓이 최대 200개까지 생성 및 연결이 되었다

 

 

backlogQ 사이즈를 SOMAXCONN으로 설정하고 테스트

소켓이 최대 200개까지 생성 및 연결이 되었다

 

 

backlog 최대 사이즈가 200인가 싶었지만 검색해보니 SOMAXCONN_HINT 가 있었다

MSDN listen

 

 

backlogQ 사이즈를 SOMAXCONN_HINT(1000) 으로 설정하고 테스트

소켓이 1000개가 생성 및 연결되었다

 

 

MSDN을 확인해보니 SOMAXCONN_HINT의 범위가 200 ~ 65535 인것 같다

 

그래서 범위 이상인 SOMAXCONN_HINT(70000) 으로 설정 테스트

 

SOMAXCONN_HINT(100)

 

SOMAXCONN_HINT(60000)

 

SOMAXCONN_HINT(14000)

 

 

backlogQ의 기본 최대 사이즈는 200

SOMAXCONN_HINT 를 사용할 경우는 200 ~ 약 14000 로 보인다

 

하지만 지금은 하나의 PC, 하나의 프로그램에서 테스트 했기 때문에 결과가 달라 질 수 있을 것 같다

'공부' 카테고리의 다른 글

TCP 파일전송 프로그램  (0) 2020.10.13
TCP 에코서버 프로그래밍  (0) 2020.10.10
도메인으로 IP 구하기  (0) 2020.10.08
20201005 월요일 정리  (0) 2020.10.06
IPv4 서브넷 연습  (0) 2020.09.26