공부

TCP 에코서버 프로그래밍

글로벌디노 2020. 10. 10. 15:35

TCP 에코 서버 / 클라이언트 프로그래밍

 

서버 코드

클라이언트 코드

 

 

실행결과

 

서버 코드

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

int main()
{
	setlocale(LC_ALL, "korean");

	WSADATA wsaData;
	int ret;

	ret = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (ret != 0)
	{
		wprintf_s(L"error WSAStartup() [%d]\n", ret);
		return 1;
	}

	SOCKET listenSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (listenSock == INVALID_SOCKET)
	{
		wprintf_s(L"error socket() [%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);

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

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

	SOCKET clientSock;
	SOCKADDR_IN clientAddr;
	int addrLen = sizeof(clientAddr);

	while (1)
	{
		// accept
		wprintf_s(L"Accept Ready ...\n");

		clientSock = accept(listenSock, (SOCKADDR*)&clientAddr, &addrLen);
		if (clientSock == INVALID_SOCKET)
		{
			wprintf_s(L"error accept() [%d]\n", WSAGetLastError());
			break;
		}

		// 연결된 소켓정보 출력
		wchar_t ipBuf[16];
		InetNtopW(clientAddr.sin_family, &clientAddr.sin_addr.s_addr, ipBuf, 16);
		wprintf_s(L"Connected IP: %s, Port: %d\n", ipBuf, ntohs(clientAddr.sin_port));

		// 데이터 통신
		while (1)
		{
			wchar_t buffer[64];
			ret = recv(clientSock, (char*)buffer, sizeof(buffer) - sizeof(wchar_t), 0);
			if (ret == 0 || ret == SOCKET_ERROR)
				break;
			buffer[ret / sizeof(wchar_t)] = L'\0';

			wprintf_s(L"%s\n", buffer);

			ret = send(clientSock, (char*)buffer, ret, 0);
			if (ret == SOCKET_ERROR)
			{
				wprintf_s(L"error send() [%d]\n", WSAGetLastError());
				break;
			}
		}

		closesocket(clientSock);
	}

	closesocket(listenSock);
	WSACleanup();

	return 0;
}

 

클라이언트 코드

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

int main()
{
	setlocale(LC_ALL, "korean");

	WSADATA wsaData;
	int ret;

	ret = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (ret != 0)
	{
		wprintf_s(L"error WSAStartup() [%d]\n", ret);
		return 1;
	}
	
	SOCKADDR_IN sockAddr;
	ZeroMemory(&sockAddr, sizeof(sockAddr));
	sockAddr.sin_family = AF_INET;
	sockAddr.sin_port = htons(7000);
	InetPtonW(AF_INET, L"127.0.0.1", &sockAddr.sin_addr);

	SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock == INVALID_SOCKET)
	{
		wprintf_s(L"error socket() [%d]\n", WSAGetLastError());
		WSACleanup();
		return 1;
	}

	ret = connect(sock, (PSOCKADDR)&sockAddr, sizeof(sockAddr));
	if (ret == SOCKET_ERROR)
	{
		wprintf_s(L"error connect() [%d]\n", WSAGetLastError());
		WSACleanup();
		return 1;
	}

	while (1)
	{
		// input string
		wprintf_s(L"send : ");
		wchar_t strBuf[64];
		fgetws(strBuf, 64, stdin);
		int len = lstrlenW(strBuf);
		if (strBuf[len - 1] == L'\n')
			strBuf[len - 1] = L'\0';

		// send
		if (send(sock, (char*)strBuf, len * sizeof(wchar_t), 0) == SOCKET_ERROR)
		{
			wprintf_s(L"error send() [%d]\n", WSAGetLastError());
			break;
		}

		// recv
		len = recv(sock, (char*)strBuf, sizeof(strBuf), 0);
		if (len == 0 || len == SOCKET_ERROR)
			break;

		wprintf_s(L"recv : %s\n", strBuf);
	}

	closesocket(sock);
	WSACleanup();
	wprintf_s(L"== Done ==\n");
	return 0;
}

 

반응형

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

Select모델 에코서버 프로그래밍  (0) 2020.10.17
TCP 파일전송 프로그램  (0) 2020.10.13
내 PC의 backlog 큐 개수 구하기  (2) 2020.10.08
도메인으로 IP 구하기  (0) 2020.10.08
20201005 월요일 정리  (0) 2020.10.06