본문 바로가기
Programming/C++

[ Windows Socket ] 소켓 프로그래밍/소켓 통신 예제 간단한 채팅 프로그램

by 코뮤(commu) 2021. 9. 17.
728x90
반응형

Server

#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h> // 윈도우즈기 때문에 들어 감 

void ErrorHandling(char * message);

int main(int argc, char *argv[]) {
	
	WSADATA wsaData; // 윈도우즈최적화 
	SOCKET hServSock, hClntSock;
	SOCKADDR_IN servAddr, clntAddr;
	
	int szClntAddr;
	char message[30];
	int strLen;
	
	
	if(argc != 2){
		printf("Usage : %s <port>\n", argv[0]);
		exit(1);
	} 
	// 윈도우즈이기 때문에 WSAStartup 이 들어감.
	//소켓 만들기 전에 들어가는데, MAKEWORD 는 버전 확인용이라고 생각하면 된다. 
	if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
		ErrorHandling("WSAStartup() error!");
	
	hServSock = socket(PF_INET, SOCK_STREAM, 0);
	if(hServSock == INVALID_SOCKET)
		ErrorHandling("socket() error");
	
	memset(&servAddr, 0, sizeof(servAddr));
	servAddr.sin_family=AF_INET;
	servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servAddr.sin_port=htons(atoi(argv[1]));
	
	if(bind(hServSock, (SOCKADDR*) &servAddr, sizeof(servAddr))==SOCKET_ERROR)
		ErrorHandling("bind() error");
	
	if(listen(hServSock, 5)==SOCKET_ERROR)
		ErrorHandling("listen() error");
	
	szClntAddr = sizeof(clntAddr);
	hClntSock = accept(hServSock, (SOCKADDR*)&clntAddr,&szClntAddr);
	if(hClntSock == INVALID_SOCKET)
		ErrorHandling("accept() error");
	while(1){
		memset(message, '\0', 30);
		strLen = recv(hClntSock, message, sizeof(message)-1, 0);
		if(strLen == -1)
			ErrorHandling("read() error!");
		printf("Message from client : %s \n", message);
		printf("메시지 입력 >>");
		gets(message);
		send(hClntSock,message,strlen(message)+1,0);
		
	}
	
	closesocket(hClntSock);
	closesocket(hServSock);
	WSACleanup();
	
	return 0;
}

void ErrorHandling(char* message){
	fputs(message, stderr);
	fputc('\n', stderr);
	exit(1);
}

 

Client

 

#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
void ErrorHandling(char* message);

int main(int argc, char *argv[]) {
	
	WSADATA wsaData;
	SOCKET hSocket;
	SOCKADDR_IN servAddr;
	
	char message[30];
	char tmp[100];
	int strLen;
	
	if(argc!=3){
		printf("Usage : %s <IP> <port>\n", argv[0]);
		exit(1);
	}
	
	if(WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
		ErrorHandling("WSAStartup() error!");
	
	hSocket = socket(PF_INET, SOCK_STREAM, 0);
	if(hSocket == INVALID_SOCKET)
		ErrorHandling("socket() error!");
	
	memset(&servAddr, 0, sizeof(servAddr));
	servAddr.sin_family = AF_INET;
	servAddr.sin_addr.s_addr = inet_addr(argv[1]);
	servAddr.sin_port=htons(atoi(argv[2]));
	
	if(connect(hSocket, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
		ErrorHandling("connect() error!");
	
	while(1){
		printf("메시지 입력 >>");
		gets(tmp);
		send(hSocket, tmp, strlen(tmp)+1,0);
		strLen = recv(hSocket, message, sizeof(message)-1, 0);
		if(strLen <= 0)
			ErrorHandling("read() error!");
		printf("Message from server : %s \n", message);
	}
	
	closesocket(hSocket);
	WSACleanup();
	
	return 0;
}

void ErrorHandling(char* message){
	fputs(message, stderr);
	fputc('\n', stderr);
	exit(1);
}

 

 

 

먼저 Server 측 코드를 먼저 실행시켜준다.

 

 

실행시킬때, 포트번호를 같이 넘겨준다.

 

 

다음 클라이언트측 코드를 실행시킨다.

 

 

 

아이피와 포트번호를 맞춰준다.

 

나는 로컬에서 진행하기 때문에 127.0.0.1 로 아이피를 설정했다.

 

 

 

 

 

클라이언트 측에서 메시지를 입력하면,

서버 측에서 바로 메시지가 보이고, 그 다음 서버 측에서 메시지를 입력하면

클라이언트에서 메시지가 보이는 형식으로 코드를 작성했다.

 

 

 

728x90
반응형