aajin126's devlog

Socket Programming을 이용한 Tic-Tac-Toe 게임 본문

Development/Game Development

Socket Programming을 이용한 Tic-Tac-Toe 게임

aajin126 2023. 6. 7. 10:15

개요

이 프로그램은 이화 Tic-Tac-Toe Protocol(ETTTP)을 구현한 Tic-Tac-Toe 게임이다. ETTTP는 서버와 클라이언트 간에 소 켓 프로그래밍을 수행하고, 게임을 플레이하기 위한 프로토콜이다. ETTTP 형식을 사용하며 보낼 데이터는 SEND로, SEND된 메시지에 대한 확인은 ACK으로 게임의 결과에 대한 데이터는 RESULT 형태로 전송된다. 클라이언트와 서버는 상대의 움직임을 이처럼 전송하고 수신하며, 유효성을 확인하며 게임이 진행된다.

Socket Programming은 네트워크 통신을 위한 프로그래밍 기술이다. Socket 은 컴퓨터 네트워크 간의 통신에 사용되는 인 터페이스로, 클라이언트와 서버 간의 데이터 교환을 가능하게 한다.

일반적으로 소켓 프로그래밍은 다음과 같은 단계로 이루어진다:

1.     서버 소켓 생성: 서버는 클라이언트의 연결 요청을 받기 위해 서버 소켓을 생성한다. 서버 소켓은 특정 포트 번호에 바인 딩되어 클라이언트의 연결을 기다린다.

2.     클라이언트 소켓 생성: 클라이언트는 서버에 연결하기 위해 클라이언트 소켓을 생성한다. 클라이언트 소켓은 서버의 IP 주소와 포트 번호를 지정하여 서버에 연결한다.

3.     연결 수립: 클라이언트는 서버의 IP 주소와 포트 번호를 이용하여 서버에 연결을 요청하고, 서버는 이를 수락하여 클라 이언트와의 연결을 수립한다.

4.     데이터 송수신: 연결이 수립된 후, 클라이언트와 서버는 소켓을 통해 데이터를 주고받을 수 있다. 클라이언트는 서버에 데이터를 전송하고, 서버는 클라이언트로부터 데이터를 수신하고 처리한다.

5.     연결 종료: 클라이언트 또는 서버가 연결을 종료하고자 할 때, 소켓을 닫아 연결을 해제합니다. 위 의 단계의 수행은 아래의 code analysis에서 자세하게 설명합니다 .

 

코드 분석

클라이언트

1.     서버와 연결하기 위한 소켓을 생성한다.

2.     클라이언트는 서버로부터 start_msg를 받고 응답을 읽는다.

3.     받은 메시지를 \r\n 기준으로 쪼개서 s_player가 ME인지 YOU인지 파악한다.

4.     메시지 정보 형태가 제대로 되어 있는지 확인한 후 형태가 제대로 되어 있지 않다면 그만 둔다. 제대로 되어 있는 경 우 계속한다.

5.     s_player가 ME이면 FIrst-Mover가 클라이언트, s_player가 YOU이면 FIrst-Mover가 서버임을 파악한다.

6.     메시지를 잘 받았다면 클라이언트는 형식에 맞춰 ack_msg를 소켓을 통해 서버로 보낸다.

7.     게임이 끝나고 연결의 필요성이 없어진다면 소켓을 닫는다.

서버

1.     클라이언트와 연결하기 위한 소켓을 생성한다.

2.     연결 요청이 오기까지 대기하고 원하는 클라이언트 요청이 오면 맞는지 확인 후 소켓을 통해 연결한다.

3.     0,1 중 하나를 택해 0이면 서버가 FIrst-Mover이고, 1이면 클라이언트가 FIrst-Mover가 되도록 정한다.

4.     이후 version, Host, First-Move 정보가 담겨 있으며 형식에 맞는 start_msg를 클라이언트에게 소켓을 통해 전송 한다.

5.     서버는 응답을 받고 ack을 제대로 수신했는지 메시지를 체크한다. 제대로 된 ack을 수신했다면 이후에 게임을 시작 한다.

6.     게임이 끝나고 연결의 필요성이 없어진다면 소켓을 닫는다.

7.     서버 소켓도 종료한다.

 

 

서버와 클라이언트의 연결이 끝난 후 TicTacToe 게임이 플레이되는데, 자신의 차례일 때는 화면에서 초록색 불이 들어오고 Ready로 뜨게 된다. 자신의 차례인 플레이어가 9칸 중 한 칸을 클릭하게 되면 send_move 함수는 입력을 받아서 location 값을 matrix 형태로 저장하고 SEND 메시지를 보낸다. 보낸 SEND 메시지는 get_move 함수가 받아서 메시지 형태에 대한 유효성을 check한 후 False가 출력되면 quit하고, 아니라면 해당 메시지에서 위치 정보를 row와 col에 저장하고, ACK 메시지를 보낸다. 저장된 위치 정보는 다시 하나의 정수(0,1,2,3,4,5,6,7,8 중 하나)로 변환되어 board에 나타나게 된다. send_moveget_move가 보낸 ACK 메시지를 받고 ACK에 대한 유효성 check를 한 후 결과 값을 return한다.

게임을 진행하는 동안 check_result로 대각선, 가로, 세로 줄이 완성되었는지 확인한다. 이 함수는 winner를 parameter로 받아 만약 ME가 winner인 경우에는 RESULT 메시지를 보내고 상대가 보내는 RESULT 메시지를 다시 확인하여 유효성을 체크한 후 상대가 보낸 RESULT 메시지에 대한 유효성과 winner 정보를 확인하고 맞다면 TRUE를 반환한다. 만약 YOU가 winner라면 상대가 보내는 RESULT 메시지를 먼저 받고 유효성을 확인한 후 내 RESULT 메시지를 보낸다. 받은 RESULT 메시지의 유효성과 winner 정보를 확인하고 맞으면 TRUE를 반환한다.

check_msg 함수는 ACK, SEND, RESULT 메시지에 대한 형태 정보를 확인해주는데, 메시지의 타입이 ACK, SEND, RESULT인지, 버전 정보가 맞는지 각각의 메시지 형태에 대한 정보를 확인하여 유효성을 반환해주는 역할을 한다. 만약 정 보가 맞지 않는다면 False를 출력하여 GUI 화면이 꺼지도록 한다.

send_debug 함수는 메시지 형태를 입력하면 거기서 위치 정보를 추출하여 그 위치가 선택 되었는지를 판단하여 선택되지 않았다면 peer에게 SEND 메시지를 보낸다. 그리고 ACK를 받아 유효성을 check 하고 False가 나올 경우 quit하고 아닐 경 우 location 정보를 loc에 저장하고 그 정보를 바탕으로 update_board를 실행한다.

 

게임 실행 화면

 

게임을 시작할 때는 2개의 console을 띄우고 server code를 먼저 실행한 후 client code를 실행한다. 


GitHub 첨부

https://github.com/aajinlee/EWHA_project

Comments