13. PC 대 PC Echo 서버- 클라이언트 구현

윤주원·2023년 7월 20일
0

컴퓨터 네트워크

목록 보기
13/15
post-thumbnail

Echo 서버/클라이언트

  • Echo
    : 반사 따위의 작용으로 충분한 진폭과 명확한 지연을 갖고 되돌아오는 파
  • Echo 서버
    : 클라이언트가 전송한 데이터를 그대로 되돌려 전송하는 기능을 가진 서버

시나리오 예시

  1. 하나의 컴퓨터에서는 Echo Server가 동작하며, 하나의 컴퓨터에서는 Echo Client가 동작한다
  2. 서버 프로그램이 먼저 시작되어 클라이언트의 접속을 대기
  3. 클라이언트 프로그램은 서버로 접근, 연결 후 클라이언트는 서버로 메시지 전송
  4. 서버는 클라이언트로부터 받은 메시지를 클라이언트에게 회신

단순 채팅 프로그램

  • 주어진 소스코드를 적절히 수정하여 다음과 같이 채팅을 주고받는 프로그램 구현
    : 서버가 클라이언트의 접속을 대기
    : 클라이언트가 먼저 채팅을 입력하고, 이를 수신한 후 서버가 채팅을 입력

클라이언트 프로그램

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32");

#define BUFSIZE 512

int main(int argc, char* argv[]) {
	WSADATA wsa;
	if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
		return -1;

	//socket()
	SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
	printf("(1) socket 생성 완료\n");

	//connect()
	SOCKADDR_IN serveraddr;
	memset(&serveraddr, 0, sizeof(serveraddr));
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_addr.s_addr = inet_addr("통신 IP 주소 입력");
	serveraddr.sin_port = htons(9000);

	connect(sock, (SOCKADDR*)&serveraddr, sizeof(serveraddr));
	printf("(2) 연결 요청보낼 문자열 입력: ");

	//send() & recv()
	while (1) {
		char buf[BUFSIZE + 1];
		printf("보낼 문자열 입력: ");
		scanf("%s", &buf);

		send(sock, buf, strlen(buf), 0);
		printf("(3) 입력 메세지 송신\n");
		if (strcmp(buf, "exit") == 0)
			break;
		int retval = recv(sock, buf, BUFSIZE, 0);
		buf[retval] = '\0';
		printf("(4) 메세지 수신: %s\n", buf);
	}
	printf("(5) 종료\n");
	closesocket(sock);
	WSACleanup();
	return 0;
}

서버 프로그램

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include<winSock2.h>
#pragma comment(lib,"ws2_32")

#define BUFSIZE 512

int main(int argc, char* argv[]) {
	int retval;

	WSADATA wsa;
	if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
		return -1;

	//socket()
	SOCKET listen_sock = socket(AF_INET, SOCK_STREAM, 0);
	printf("(1) socket 생성 완료\n");

	//bind()
	SOCKADDR_IN serveraddr;
	memset(&serveraddr, 0, sizeof(serveraddr));
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
	serveraddr.sin_port = htons(9000);
	bind(listen_sock, (SOCKADDR*)&serveraddr, sizeof(serveraddr));
	printf("(2) bind 완료.\n");

	//listen()
	listen(listen_sock, SOMAXCONN);
	printf("(3) 클라이언트 대기 중\n");

	SOCKET client_sock;
	SOCKADDR clientaddr;
	int addrlen;
	char buf[BUFSIZE];
	char test[BUFSIZ];
	//accept()
	addrlen = sizeof(clientaddr);
	client_sock = accept(listen_sock, (SOCKADDR*)&clientaddr, &addrlen);
	printf("(4) 연결 수락 요청\n");

	//recv() & send()
	while (1) {
		retval = recv(client_sock, buf, BUFSIZE, 0);
		buf[retval] = '\0';
		printf("(5) 메시지 수신 : %s\n", buf);
		if (strcmp(buf, "exit") == 0)
			break;
		printf("보낼 문자 입력 : ");
		scanf("%s", &test);
		send(client_sock, test, strlen(test), 0);
		printf("(6) Echo 메시지 송신\n");
	}
	printf("(7) 종료\n");
	closesocket(listen_sock);
	WSACleanup();
	return 0;
}

결과

  • 서버(서버가 반드시 먼저 실행)
  • 클라이언트

profile
안녕하세요

1개의 댓글

comment-user-thumbnail
2023년 7월 20일

글이 많은 도움이 되었습니다, 감사합니다.

답글 달기