Server/C++

UDP 소켓 프로그래밍

Juzdalua 2024. 8. 6. 22:35

UDP 서버는 수신할 대상을 지정하지 않는다.


Unconnected UDP

매번 송수신할 때 마다 서버의 정보를 입력한다.

// sendto
int32 resultCode = sendto(clientSocket, sendBuffer, sizeof(sendBuffer), 0, (SOCKADDR*)&serverAddr, sizeof(serverAddr));

// recvfrom
int32 recvLen = recvfrom(clientSocket, recvBuffer, sizeof(recvBuffer), 0, (SOCKADDR*)&recvAddr, &addrLen);

 

Connected UDP

connect 함수에 서버 정보를 한번만 입력한다. -> TCP와 유사

// send
connect(clientSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr));
int32 resultCode = send(clientSocket, sendBuffer, sizeof(sendBuffer), 0);

// recv
int32 recvLen = recv(clientSocket, recvBuffer, sizeof(recvBuffer), 0);

// client

#include "pch.h"
#include <iostream>

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

void HandleError(const char* cause)
{
	int32 errCode = WSAGetLastError();
	cout << cause << " ErrorCode: " << errCode << endl;
}

int main()
{
	// 1. Socket 초기화
	WSAData wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
		return 0;

	SOCKET clientSocket = socket(AF_INET, SOCK_DGRAM, 0);
	if (clientSocket == INVALID_SOCKET)
	{
		HandleError("Socket");
		return 0;
	}

	// 2. IP, PORT 설정 
	char IP[] = "127.0.0.1";
	u_short PORT = 7777;

	SOCKADDR_IN serverAddr; // IPv4
	memset(&serverAddr, 0, sizeof(serverAddr));
	serverAddr.sin_family = AF_INET;
	inet_pton(AF_INET, IP, &serverAddr.sin_addr);
	serverAddr.sin_port = htons(PORT);

	// Connected UDP
	connect(clientSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr));

	// 3. 데이터 송수신
	while (true)
	{
		char sendBuffer[100] = "Hello World!";

		// sendto -> 클라이언트의 IP주소, 포트번호 설정
		// Unconnected UDP
		//int32 resultCode = sendto(clientSocket, sendBuffer, sizeof(sendBuffer), 0, (SOCKADDR*)&serverAddr, sizeof(serverAddr));

		// Connected UDP
		int32 resultCode = send(clientSocket, sendBuffer, sizeof(sendBuffer), 0);
		if (resultCode == SOCKET_ERROR)
		{
			HandleError("SendTo");
			return 0;
		}

		cout << "Send Data! Len = " << sizeof(sendBuffer) << endl;

		// Echo Receiver
		{
			SOCKADDR_IN recvAddr;
			memset(&recvAddr, 0, sizeof(recvAddr));
			int32 addrLen = sizeof(recvAddr);

			char recvBuffer[1000];

			// Unconnected UDP
			//int32 recvLen = recvfrom(clientSocket, recvBuffer, sizeof(recvBuffer), 0, (SOCKADDR*)&recvAddr, &addrLen);

			// Connected UDP
			int32 recvLen = recv(clientSocket, recvBuffer, sizeof(recvBuffer), 0);

			if (recvLen <= 0)
			{
				HandleError("RecvFrom");
				return 0;
			}

			cout << "Recv Data! Len = " << recvLen << endl;
			cout << "Recv Data! Data = " << recvBuffer << endl;
		}

		this_thread::sleep_for(1s);
	}

	// 4. Socket 종료
	closesocket(clientSocket);
	WSACleanup();
}
// server

#include "pch.h"
#include "CorePch.h"
#include "CoreMacro.h"
#include "ThreadManager.h"
#include <iostream>

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

void HandleError(const char* cause)
{
	int32 errCode = WSAGetLastError();
	cout << cause << " ErrorCode: " << errCode << endl;
}

int main()
{
	WSAData wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
		return 0;

	SOCKET serverSocket = socket(AF_INET, SOCK_DGRAM, 0);
	if (serverSocket == INVALID_SOCKET)
	{
		HandleError("Socket");
		return 0;
	}

	u_short PORT = 7777;
	SOCKADDR_IN serverAddr; // IPv4
	memset(&serverAddr, 0, sizeof(serverAddr));
	serverAddr.sin_family = AF_INET;
	serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
	serverAddr.sin_port = htons(PORT);

	if (::bind(serverSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)
	{
		HandleError("Bind");
		return 0;
	}

	while (true)
	{
		SOCKADDR_IN clientAddr;
		memset(&clientAddr, 0, sizeof(clientAddr));
		int32 addrLen = sizeof(clientAddr);

		char recvBuffer[1000];
		int32 recvLen = recvfrom(serverSocket, recvBuffer, sizeof(recvBuffer), 0, (SOCKADDR*)&clientAddr, &addrLen);

		if (recvLen <= 0) {
			HandleError("RecvFrom");
			return 0;
		}

		cout << "Recv Data! Len = " << recvLen << endl;
		cout << "Recv Data! Data = " << recvBuffer << endl;

		// Echo Server
		int32 errCode = sendto(serverSocket, recvBuffer, recvLen, 0, (SOCKADDR*)&clientAddr, sizeof(clientAddr));
		if (errCode == SOCKET_ERROR)
		{
			HandleError("SendTo");
			return 0;
		}

		cout << "Send Data! Len = " << sizeof(recvLen) << endl;
	}

	WSACleanup();
}

'Server > C++' 카테고리의 다른 글

논블로킹 소켓 (Non-Blocking Socket)  (0) 2024.08.07
Socket option  (0) 2024.08.06
TCP vs UDP  (0) 2024.08.06
TCP 소켓 프로그래밍  (0) 2024.08.06
TypeCase  (0) 2024.08.06