TCP 비동기? IP 주소 치고 CONNECT

#include <iostream>
#include <WS2tcpip.h>
#include <WinSock2.h>
#include <set>
using namespace std;
#pragma comment (lib, "Ws2_32.lib") // cpp

/*
*	기본 자료형
	int, float, bool,
*/
/*
	사용자정의 자료형

	struct 구조체명
	{
		자료형 멤버변수명;
		자료형 멤버변수명2;
	};

	int num;

	구조체명 변수명;

	변수명.멤버변수명 = 값;
*/
struct ClientInfo
{
	WSAOVERLAPPED	overlapped;

	SOCKET			socket;
	char			buffer[512];
	WSABUF			dataBuf;
	DWORD			recvByte;
	DWORD			flags;
	BOOL			isSend;
};

/*
	자료구조

		구현이 쉽다.
		임의접근에 유리하다.
		삽입삭제에 유리하다.

		다 준수하면서 검색(탐색)에 능하다.
		map, set

		탐색,  검색

*/

set<ClientInfo*>	g_clientList;

void CALLBACK RecvCallBackFunc(DWORD _error, DWORD _recvLen, LPWSAOVERLAPPED _overlapped, DWORD _inflags)
{
	ClientInfo* info = (ClientInfo*)_overlapped;

	if (_recvLen == 0)
	{
		cout << "클라 연결 종료" << endl;
		closesocket(info->socket);

		g_clientList.erase(info);

		delete info;

		return;
	}

	if (_error == 0)
	{
		if (info->isSend == false)
		{
			cout << "받았다" << endl;
			cout << "수신 메시지 : " << info->buffer << endl;

			for (auto iter = g_clientList.begin(); iter != g_clientList.end(); iter++)
			{
				ClientInfo* data = *iter;

				strcpy_s(data->dataBuf.buf, 512, info->dataBuf.buf);
				data->dataBuf.len = _recvLen;

				WSASend(
					data->socket,
					&data->dataBuf,
					1,
					nullptr,
					0,
					&data->overlapped,
					RecvCallBackFunc);

				data->isSend = true;
			}
		}
		else
		{
			info->dataBuf.len = 512;

			WSARecv(
				info->socket,
				&info->dataBuf,
				1,
				&info->recvByte,
				&info->flags,
				&info->overlapped,
				RecvCallBackFunc);

			cout << "수신대기 시작" << endl;

			info->isSend = false;
		}
	}
}

int main()
{
	//	WSAStartup
	WSADATA	wsa;
	int		result;

	result = WSAStartup(MAKEWORD(2, 2), &wsa);

	if (result != 0)
	{
		cout << "WSAStartup 에러" << endl;
		return -1;
	}

	//	소켓 생성
	SOCKET	mySocket = WSASocket(
		AF_INET,
		SOCK_STREAM,
		0,
		nullptr,
		0,
		WSA_FLAG_OVERLAPPED);

	if (mySocket == INVALID_SOCKET)
	{
		cout << "소켓 생성 에러" << endl;
		WSACleanup();
		return -1;
	}

	//	바인딩
	sockaddr_in		recviverAddr = {};
	recviverAddr.sin_family = AF_INET;
	recviverAddr.sin_port = htons(12345);
	recviverAddr.sin_addr.s_addr = INADDR_ANY;

	result = bind(
		mySocket,
		(sockaddr*)&recviverAddr,
		sizeof(recviverAddr));

	if (result != 0)
	{
		cout << "바인딩 에러" << endl;
		closesocket(mySocket);
		WSACleanup();
		return -1;
	}

	//	리슨
	if (listen(mySocket, SOMAXCONN) == SOCKET_ERROR)
	{
		cout << "리슨 에러" << endl;
		closesocket(mySocket);
		WSACleanup();
	}

	SOCKET clientSocket;

	while (true)
	{
		cout << "연결 대기 시작" << endl;

		//	어셉
		clientSocket = accept(mySocket, nullptr, nullptr);

		if (clientSocket == INVALID_SOCKET)
		{
			cout << "어셉 에러" << endl;
			closesocket(mySocket);
			WSACleanup();
			return -1;
		}

		cout << "클라 연결 성공" << endl;

		ClientInfo* info = new ClientInfo;
		info->socket = clientSocket;
		info->dataBuf.buf = info->buffer;
		info->dataBuf.len = 512;
		info->flags = 0;
		info->recvByte = 0;
		info->isSend = false;

		//	리스트에 클라 정보 저장
		g_clientList.insert(info);

		//	웰컴 멘트 제작
		strcpy_s(info->dataBuf.buf, info->dataBuf.len, "system : welcome");
		info->dataBuf.len = strlen("system : welcome");

		//	송신
		WSASend(
			info->socket,
			&info->dataBuf,
			1,
			nullptr,
			0,
			&info->overlapped,
			RecvCallBackFunc);

		info->isSend = true;
	}

	//	해제들
	closesocket(clientSocket);
	closesocket(mySocket);
	WSACleanup();

	return 0;
}

클래스


디자인패턴

상태패턴

#include <iostream>
#include <random>
using namespace std;

/*
	상태패턴

*/

class Monster
{
public:
	int m_nHP{};
	int m_nAtk{};
	string m_strName{};

	Monster()
	{
		m_nHP = 20;
		m_nAtk = 5;
		m_strName = "이름";
	}

	virtual void Attack(int* _hp, int* _atk, int nInput = 0) // 디폴트 매개변수
	{
		*_hp -= m_nAtk;
	}

	virtual void Heal(int nInput = 0)
	{
		m_nHP += m_nAtk;
	}
};

class Monster1 : public Monster
{
public:
	Monster1()
	{
		m_nAtk = 20;
		m_nHP = 50;
		m_strName = "Monster1";
	}

	void Attack(int* _hp, int* _atk, int nInput = 0) // 디폴트 매개변수
	{
		cout << m_nAtk << "의 피해를 주었다." << '\\n';
		*_hp -= m_nAtk;
	}

	void Heal(int nInput = 0)
	{
		cout << m_nAtk << "만큼 회복했다." << '\\n';
		m_nHP += m_nAtk;
	}
};

class Monster2 : public Monster
{
public:
	Monster2()
	{
		m_nAtk = 100;
		m_nHP = 20;
		m_strName = "Monster2";
	}

	void Attack(int* _hp, int* _atk, int nInput = 0) // 디폴트 매개변수
	{
		cout << m_nAtk << "의 피해를 주었다." << '\\n';
		*_hp -= m_nAtk;
	}

	void Heal(int nInput = 0)
	{
		cout << m_nAtk << "만큼 회복했다." << '\\n';
		m_nHP += m_nAtk;
	}
};

class Monster3 : public Monster
{
public:
	Monster3()
	{
		m_nAtk = 10;
		m_nHP = 200;
		m_strName = "Monster3";
	}

	void Attack(int* _hp, int* _atk, int nInput = 0) // 디폴트 매개변수
	{
		cout << m_nAtk << "의 피해를 주었다." << '\\n';
		*_hp -= m_nAtk;
	}

	void Heal(int nInput = 0)
	{
		cout << m_nAtk << "만큼 회복했다." << '\\n';
		m_nHP += m_nAtk;
	}
};

int main()
{
	srand(time(nullptr));

	int nHP = 1000;
	int nAtk = 50;

	int nInput{};
	int nMonsterInput{};

	while (true)
	{
		Monster* monster = nullptr;

		int nType = rand() % 3;

		switch (nType)
		{
		case 0:
			monster = new Monster1{};
			break;
		case 1:
			monster = new Monster2{};
			break;
		case 2:
			monster = new Monster3{};
			break;
		default:
			monster = new Monster;
		}

		while (true)
		{
			cout << "HP : " << nHP << '\\n';
			cout << monster->m_strName << "가 나타났다!" << '\\n';
			cout << "Monster HP : " << monster->m_nHP << '\\n';

			if (nHP <= 0)
			{
				cout << "패배" << '\\n';
				break;
			}
			else if (monster->m_nHP <= 0)
			{
				cout << "승리" << '\\n';
				break;
			}

			cout << "1. 공격 2. 회복" << '\\n';
			cout << "입력 : ";

			int nInput{};
			cin >> nInput;

			switch (nInput)
			{
			case 1:
				cout << "플레이어가 공격합니다." << '\\n';
				monster->m_nHP -= nAtk;
				break;
			case 2:
				cout << "플레이어가 회복합니다." << '\\n';
				nHP += nAtk;
				break;
			}

			nMonsterInput = rand() % 2 + 1;

			switch (nMonsterInput)
			{
			case 1:
				monster->Attack(&nHP, &nAtk, nInput);
				break;
			case 2:
				monster->Heal(nInput);
				break;
			}

			system("pause");
			system("cls");
		}

		delete monster;

		cout << "Continue? / 0.끝 1.계속" << '\\n';
		cout << "입력 : ";
		cin >> nInput;

		if (nInput == 0)
		{
			break;
		}
		else
		{
			nHP = 1000;
			system("cls");
		}
	}
}