C# 공부/[C#] 프로그램 개발

[C# Winform 채팅 프로그램 개발 002] TCP/IP 통신 프로토콜 정의서

햅2024 2024. 11. 8. 19:42

1.    개요

본 문서의 목적은 채팅프로그램 서버와 클라이언트 간의 통신 방법을 정의합니다.

 

1.1.    통신 규격

  서버,클라이언트간 통신은 TCP/IP 통신을 따른다.

(1)   Server : 채팅 서버

(2)   Client : Client(API를 이용하여 접속하는 클라이언트)

(3)   JSON 인코딩

-       JSON 인코딩은 UTF-8 을 사용

(4)   기본 포트는 6666을 사용하며 Setting 창에서 변경할 수 있다.

 

1.2.    데이터 표현 방식

각 패킷의 헤더는 C# 구조체 형태로 정의하고 데이터는 JSON 형식을 사용 합니다.

(주의 : 각 구조체의 packing alignment1byte로 한다. #pragma pack( push, 1 )를 사용해야함)

타입 크기 설명
BYTE 1 1 바이트 크기를 가진 정수형 (범위: 0~255, unsigned char)
CHAR 1 1 바이트 크기를 가진 정수형 (범위: -128~127, char)
Short 2 2 바이트 크기를 가진 정수형 (범위: -32,768~32,768)
Int 4 4 바이트 크기를 가진 정수형 (범위: -2,147,483,648 ~ 2,147,483,647, unsigned int)
UINT 4 4 바이트 크기를 가진 정수형 (범위: 0~4,294,967,295, unsigned int)
Long 8 8 바이트 크기를 가진 정수형 (범위: -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,808)
FLOAT 4 4 바이트 크기를 가진 부동 소수점 (float)
DOUBLE 8 8 바이트 크기를 가진 부동 소수점 (double)

 

 

 

2.  Protocol Designs

2.1.    Packet 구조

각 패킷은 아래 그림과 같이 패킷 헤더(Packet Header)와 패킷 데이터(Packet data payload)로 구성된다. (, 경우에 따라서 패킷 헤더만 전송될 수도 있다.)

2.2.    Packet Header

패킷 헤더는 아래와 같이 바이트 크기를 가진다.

// Packcet Header 구조

struct PacektHeader

{

           BYTE     prefix[3];            // 패킷 구분자 "REX"

           BYTE     OPCODE;           // 명령 코드

           UINT     Length;             // body packet 길이

           BYTE     Reserve[8];        

};

 

l  prefix : Center 패킷 임을 구분하기 위한 구분자. 항상 ASCII 문자 “RXMG.

l  OPCODE : 패킷의 동작을 정의하는 명령 코드 (아래 명령 코드표 참고)

l  Length : body Packet의 길이

 

2.3.    Packet Data

l  패킷 데이터는 JSON 구조를 갖는다

l  JSON 데이터는 UTF-8으로 인코딩 한다

l  Packet 1400byte를 기준으로 한다. 대용량 시 1400byte 씩 분할하여 전송한다.

3.  코드 정의

3.1.    명령 코드 정의

채팅프로그램에서 사용되는 세부 프로토콜은 다음과 같다

OPCODE 설명 전송 주기 요청 필요 여부 통신방향
0x01 채팅 전송 채팅 발송 시 X C <-> S
0x02 채팅 ACK 전송 채팅 수신 시 X C <-> S
0x03 이미지 파일 전송 이미지 파일 발송 시 X C <-> S
0x04 이미지 ACK 전송 이미지 파일 수신 시 X C <-> S
0x05 대용량 파일 전송 대용량 파일 발송 시 X C <-> S
0x06 대용량 파일 전송 대용량 파일 수신 시 X C <-> S

 

4.  패킷 데이터 정의

4.1.    채팅 (OPCODE = 0x01)

서버 및 클라이언트에서 채팅을 발송할 시에는 채팅 코드를 전달하여 메시지를 구분하여 처리합니다.

 

l 전송 메시지 구성(Client <-> Server)

이름 타입 길이 설명
PREFIX BYTE 3 패킷 구분자 “REX”
OPCODE BYTE 1 0x01
Length UINT 4 BodyPacket Byte Length
Reserve BYTE 8  
Data
{
   “date” : “2024-05-16 11:33:21”,
   “nickname” : “User”,
   “message” : “안녕
}
Data 설명
이름 타입 길이 설명
date String   채팅 발송 시간 값. 형식: yyyy-MM-dd HH:mm:ss
nickname String   발송자의 닉네임
message String   발송자 채팅 메세지

 

4.2.  채팅 ACK (OPCODE = 0x02)

채팅 수신 완료 시, Ack 값을 송신합니다.

l 전송 메시지 구성(Client <-> Server)

이름 타입 길이 설명
PREFIX BYTE 3 패킷 구분자 “REX”
OPCODE BYTE 1 0x02
Length UINT 4 BodyPacket Byte Length
Reserve BYTE 8  
Data
{
   “ack” : 0
}
Data 설명
이름 타입 길이 설명
ack int 8 0 송신 성공
1 HeaderPacket 없음
2 Header length값과 body length 값 불일치
3 예외처리 오류 발생

 

 

4.3.    이미지 파일 (OPCODE = 0x03)

서버 및 클라이언트에서 이미지 파일을 발송할 시에는 이미지 코드를 전달하여 메시지를 구분하여 처리합니다. 이미지 파일 OPCODE 송신 시, 이미지파일 다운로드 후 Image Viewer 통해 해당 이미지를 보여줍니다.

l 전송 메시지 구성(Client <-> Server)

이름 타입 길이 설명
PREFIX BYTE 3 패킷 구분자 “REX”
OPCODE BYTE 1 0x03
Length UINT 4 BodyPacket Byte Length
Reserve BYTE 8  
Data
{
   “date” : “2024-05-16 11:33:21”,
   “nickname” : “User”,
   “imagefile” : //Base64String 형식의 이미지파일
}
Data 설명
이름 타입 길이 설명
date String   채팅 발송 시간 값. 형식: yyyy-MM-dd HH:mm:ss
nickname String   발송자의 닉네임
imagefile String   발송하는 이미지 파일을 Base64string으로 변환한 값

 

4.4.  이미지파일 ACK (OPCODE = 0x04)

이미지파일 수신 완료 시, Ack 값을 송신합니다.

l 전송 메시지 구성(Client <-> Server)

이름 타입 길이 설명
PREFIX BYTE 3 패킷 구분자 “REX”
OPCODE BYTE 1 0x04
Length UINT 4 BodyPacket Byte Length
Reserve BYTE 8  
Data
{
   “ack” : 0
}
Data 설명
이름 타입 길이 설명
ack int 8 0 송신 성공
1 HeaderPacket 없음
2 Header length값과 body length 값 불일치
3 예외처리 오류 발생

 

4.5.    대용량 파일 (OPCODE = 0x05)

서버 및 클라이언트에서 대용량 파일을 발송할 시에는 대용량 코드를 전달하여 메시지를 구분하여 처리합니다.

 

l 전송 메시지 구성(Client <-> Server)

이름 타입 길이 설명
PREFIX BYTE 3 패킷 구분자 “REX”
OPCODE BYTE 1 0x01
Length UINT 4 BodyPacket Byte Length 
Reserve BYTE 8  
Data
{
   “date” : “2024-05-16 11:33:21”,
   “nickname” : “User”,
   file
}
Data 설명
이름 타입 길이 설명
date String   채팅 발송 시간 값. 형식: yyyy-MM-dd HH:mm:ss
nickname String   발송자의 닉네임
file String   대용량 파일 변환

 

4.6.  대용량 파일 ACK (OPCODE = 0x06)

대용량 파일 수신 완료 시, Ack 값을 송신합니다.

l 전송 메시지 구성(Client <-> Server)

이름 타입 길이 설명
PREFIX BYTE 3 패킷 구분자 “REX”
OPCODE BYTE 1 0x02
Length UINT 4 BodyPacket Byte Length 
Reserve BYTE 8  
Data
{
   “ack” : 0
}
Data 설명
이름 타입 길이 설명
ack int 8 0 송신 성공
1 HeaderPacket 없음
2 Header length값과 body length 값 불일치
3 예외처리 오류 발생