본문 바로가기
프로그래밍/C++

C++ 소켓 프로그래밍(Socket Programming) 에코 서버

by bantomak 2024. 7. 31.
반응형

에코 서버(Echo Server) 만들기

C++로 소켓 프로그래밍을 공부할 때 가장 기본이 되는 서버는 클라이언트로부터 문자열을 수신받아서 해당 문자열을 그대로 송신하는 일명 에코서버를 작성해 보는 것이다. 에코 서버를 작성하면서 소켓 프로그래밍의 기본적인 작동 흐름에 대해서 배워보도록 하자.

 

전반적인 흐름에 대해서 정리해보자면

  • 소켓 생성
  • IP, PORT 소켓에 바인딩
  • listen()으로 클라이언트 접속 대기 상태로 전환하기
  • accept()로 클라이언트와 연결하기
  • recv(), send() 사용해서 클라이언트와 문자열 주고받기

 

예제 코드

#include <stdio.h>
#include <winsock2.h>
#include <tchar.h>

#pragma comment(lib, "ws2_32.lib")

int _tmain(int argc, _TCHAR* argv[])
{
	WSAData wsa = { 0 };
	if (::WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
	{
		puts("wsa startup fail");
		return 0;
	}

	SOCKET hSocket = ::socket(AF_INET, SOCK_STREAM, 0);
	if (hSocket == INVALID_SOCKET)
	{
		puts("socket init fail");
		return 0;
	}

	SOCKADDR_IN svrAddr = { 0 };
	svrAddr.sin_family = AF_INET;
	svrAddr.sin_port = htons(25000);
	svrAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

	if (::bind(hSocket, (SOCKADDR*)&svrAddr, sizeof(svrAddr)) == SOCKET_ERROR)
	{
		puts("bind fail");
		return 0;
	}

	if (::listen(hSocket, SOMAXCONN) == SOCKET_ERROR)
	{
		puts("listen fail");
		return 0;
	}

	SOCKADDR_IN clientAddr = { 0 };
	int clientSize = sizeof(clientAddr);
	SOCKET hClient = 0;
	char szBuffer[128] = { 0 };
	int nReceive = 0;

	while ((hClient = ::accept(hSocket, (SOCKADDR*)&clientAddr, &clientSize)) != INVALID_SOCKET)
	{
		puts("new client connect.");

		while ((nReceive = ::recv(hClient, szBuffer, sizeof(szBuffer), 0)) > 0)
		{
			puts(szBuffer);
			::send(hClient, szBuffer, sizeof(szBuffer), 0);
			memset(szBuffer, 0, sizeof(szBuffer));
		}

		puts("client disconnect.");

		::closesocket(hClient);
	}

	::shutdown(hSocket, SD_BOTH);
	::closesocket(hSocket);

	::WSACleanup();

	return 0;
}

 

가장 기본이 되는 에코서버 코드이다. 여러 번 직접 쳐보면서 학습하도록 하자.

댓글