Computer Science/Network

Window C 소켓 통신(Server/Client) 코드

이진2 2020. 2. 16. 17:41

Window C 환경에서 Socket을 사용해서 서버와 클라이언트가 채팅으로 통신하는 프로그램입니다

* 한 솔루션에서 멀티 프로젝트를 생성하여 실행했습니다🤭

 

일단 각각의 프로젝트에서 독립 실행을 위해 솔루션-속성-공용 속성-시작프로젝트에서 현재 시작영역을 체크해줍니다

또한 윈도우 환경에서 TCP/IP 소켓을 사용하기 위해 각각의 프로젝트에서

프로젝트 '속성'->'구성 속성'->'입력'->'추가 종속성'->ws2_32.lib 을 추가해줍니다!!

 

각각의 헤더파일과 소스코드는 다음과 같습니다

Server.h

#ifndef SERVER_MAIN_H
#define SERVER_MAIN_H

#include <WinSock2.h>
#include <iostream>
#include <fstream>
#include <string.h>
using namespace std;

#include <chrono>
#include <string>
#include <stdexcept>

#define SERVER_PORT 11235
#define BUF_SIZE 4096
#define QUEUE_SIZE 10
#define IPAddress "127.0.0.1"

#pragma warning(disable:4996)

#endif

#pragma once

Server.c

#include "server.h"

int main(void) {
	WORD	wVersionRequested;
	WSADATA	wsaData;
	SOCKADDR_IN servAddr, cliAddr;
	int	err, check;
	int	bytesSent;
	char	buf[BUF_SIZE], cur[50];

	wVersionRequested = MAKEWORD(1, 1);
	err = WSAStartup(wVersionRequested, &wsaData);

	if (err) {
		cout << "WSAStart up error" << WSAGetLastError() << endl;
		WSACleanup();
		return false;
	}

	servAddr.sin_family = AF_INET;
	servAddr.sin_port = htons(SERVER_PORT);
	servAddr.sin_addr.s_addr = inet_addr(IPAddress);

	SOCKET serv = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (serv == INVALID_SOCKET) {
		cout << "Socket error" << WSAGetLastError() << endl;
		WSACleanup();
		return false;
	}

	int x = bind(serv, reinterpret_cast<SOCKADDR*>(&servAddr), sizeof(servAddr));
	if (x == SOCKET_ERROR) {
		cout << "Binding failed. Error code: " << WSAGetLastError() << endl;
		WSACleanup();
		return false;
	}

	cout << "Waiting for client ... " << endl;

	listen(serv, 5);
	int xx = sizeof(cliAddr);
	SOCKET cli = accept(serv, reinterpret_cast<SOCKADDR*>(&cliAddr), &xx);
	cout << "Connection established. Socket number is " << cli << endl;

	int iRand = 0;

	while (1) {
		try {
			check = recv(cli, buf, sizeof(buf), 0);
			if (check <= 0) { cout << "End of Sending" << endl; break; }
			buf[check] = '\0';

			cout << "Received: " << endl << buf << endl << endl;// << "  sizeof= " << check << endl << endl;
		}
		catch (const invalid_argument & ex) {
			cerr << "Invalid argument while converting string to number" << endl;
			cerr << "Error: " << ex.what() << endl;
			break;
		}
		catch (const out_of_range & ex) {
			cerr << "Invalid argument while converting string to number" << endl;
			cerr << "Error: " << ex.what() << endl;
			break;
		}

	}
	closesocket(serv);
	WSACleanup();

	return 0;
}

Client.h

#ifndef CLIENT_MAIN_H
#define CLIENT_MAIN_H

#include <WinSock2.h>
#include <iostream>
using namespace std;

#include <thread>
#include <chrono>

#include <string>
#include <stdexcept>

#define SERVER_PORT 11235
#define BUF_SIZE 4096
#define QUEUE_SIZE 10
#define IPAddress "127.0.0.1"

#pragma warning(disable:4996)

#endif

#pragma once

Client.c

#include "client.h"

int main() {
	WORD wVersionRequested;
	WSADATA	wsaData;
	SOCKADDR_IN target;
	SOCKET		cli;
	int	err;
	int bytesSent;
	string buf;

	wVersionRequested = MAKEWORD(1, 1);
	err = WSAStartup(wVersionRequested, &wsaData);

	if (err) {
		cout << "WSAStartup error " << WSAGetLastError() << endl;
		WSACleanup();
		return 0;
	}

	target.sin_family = AF_INET;
	target.sin_port = htons(SERVER_PORT);
	target.sin_addr.s_addr = inet_addr(IPAddress);

	cli = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (cli == INVALID_SOCKET) {
		cout << "socet() error: " << WSAGetLastError() << endl;
		WSACleanup();
		return 0;
	}

	if (connect(cli, reinterpret_cast<SOCKADDR*>(&target), sizeof(target)) == SOCKET_ERROR) {
		cout << "socet() error: " << WSAGetLastError() << endl;
		WSACleanup();
		return 0;
	}

	cout << "Server Connect Success"<<endl<<endl;
	
	while (1) {
		try {
			cout << "Sending : ";
			cin >> buf;
			send(cli, buf.c_str(), buf.length(), 0);
		}
		catch (const invalid_argument & ex) {
			cerr << "Invalid argument while converting string to number" << endl;
			cerr << "Error: " << ex.what() << endl;
			break;
		}
		catch (const out_of_range & ex) {
			cerr << "Invalid argument while converting string to number" << endl;
			cerr << "Error: " << ex.what() << endl;
			break;
		}

	}

	closesocket(cli);
	WSACleanup();
}

서버를 실행시킨 뒤 클라이언트를 실행시켜주면 다음과 같습니다 ʕ∙ჲ∙ʔ

 

 

 

++