이것은 최신 Raknet 프로토콜 문서입니다. 여기에는 프로토콜에 사용 된 데이터 유형에 대한 정보와 각 패킷 및 관련 필드에 대한 세부 정보가 포함됩니다.
TODO : 눈을 더 좋게 만들고 쓸모없는 것들을 많이 제거하십시오. 또한 열거/상수와 같은 물건을 1 장소로 구성하고 반복적 인 물건을 제거하십시오.
이 문서는 Libcat의 유사한/동일한 보안 방법을 원한다고 가정하므로, 대상이있는 서버에 Libcat이 있거나 그와 동일하지 않은 경우 보안을 활성화 한 경우 클라이언트는 쿠키, 신원 증명 또는 좋아하는 것만 제공하지 않기 때문에 클라이언트가 충돌합니다. 그러나 두 경우 모두 지원 요청을 가져올 수 있습니다.
| 유형 | 크기 | 메모 |
|---|---|---|
| UINT8 | 1 바이트 | 서명되지 않은 8 비트 정수 |
| UINT16 | 2 바이트 | 서명되지 않은 16 비트 정수 |
| UINT24 | 3 바이트 | 최소 값이 0이고 최대 값이 16777215 인 서명되지 않은 24 비트 정수 |
| UINT32 | 4 바이트 | 서명되지 않은 32 비트 정수 |
| UINT64 | 4/8 바이트 | 서명되지 않은 64 비트 정수 (32 비트 시스템의 경우 4 바이트, 64 비트 시스템의 경우 8 바이트) |
| UINT16 스트링 | 변하기 쉬운 | 문자열 앞에 2 바이트의 길이를 가진 UTF-8 인코딩 된 문자열 |
| 마법 | 16 바이트 | 특정 시퀀스가있는 서명되지 않은 8 비트 정수의 배열 [0x00, 0xFF, 0xFF, 0x00, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFD, 0xFD, 0x12, 0x34, 0x56, 0x78] |
| 영역이있는 패드 | 변하기 쉬운 | 선택한 크기의 패딩에 사용되는 Null 바이트 |
| 부 | 1 바이트 | 0 또는 1의 값을 가진 단일 서명되지 않은 8 비트 정수로 작성하거나 읽으십시오 (0은 False를 나타내는 데 사용되며 하나는 True를 나타내는 데 사용됩니다). |
| 주소 | 7-29 바이트 | IPv4 : 1 바이트 (주소 버전), 4 바이트 (IP 주소), 2 바이트 (포트), IPv6 : 1 바이트 (주소 버전), 주소 패밀리 (Little-Endian)에 대한 서명되지 않은 짧은 짧은 짧은 짧은 짧은 짧은 짧은 짧은 짧은 짧은 짧은 짧은 짧은 짧은 짧게, 흐름 정보에 대한 서명되지 않은 정수, 스코프 ID에 대한 16 바이트. |
| 조금 | 1 비트 | 완료 한 후 버퍼 내부의 비트를 쓰거나 읽으십시오. |
| 뜨다 | 4 바이트 | IEEE 754 단일-정밀 플로팅 지점 번호 |
구현을 더 빨리 만들고 싶다면 어떻게 만들어 졌는지 읽지 않고 즉시 정의 할 수 있습니다.
| 이름 | 값 |
|---|---|
| mtusize | 1492 |
| udpheadersize | 28 |
| 공개 키즈 | 294 |
| requstchallendsize | 64 |
| 응답 암호화 키 | 128 |
| MaxNumberoflocaladdresses | 10 |
| IdentityProofsize | 294 |
| ClientProofSize | 32 |
| DefaultProtocolversion | 6 |
| 숫자가 rangedstreams | 32 |
| 이름 | ID | 유형 |
|---|---|---|
| 연결되지 않은 | 0x01 | 오프라인 |
| 연결되지 않은 핀 앤 컨칭 | 0x02 | 오프라인 |
| 연결되지 않은 폰 | 0x1c | 오프라인 |
| 연결 | 0x00 | 온라인 [/datagram에서] |
| ConnectedPong | 0x03 | 온라인 [/datagram에서] |
| OpenConnectionRequestone | 0x05 | 오프라인 |
| OpenConnectionReplyOne | 0x06 | 오프라인 |
| OpenConnectionRequesttwo | 0x07 | 오프라인 |
| OpenConnectionReplyTwo | 0x08 | 오프라인 |
| ConnectionRequest | 0x09 | 온라인 [/datagram에서] |
| RemotesystemRequirespublickey | 0x0A | 오프라인 |
| OurSystemRequiressecurity | 0x0b | 둘 다 [?] |
| ConnectionAtMpeMpfailed | 0x11 | 오프라인 |
| 이미 연결되어 있습니다 | 0x12 | 오프라인 |
| ConnectionRequestected | 0x10 | 온라인 [/datagram에서] |
| NewincomingConnection | 0x13 | 온라인 [/datagram에서] |
| 연결이 끊김 | 0x15 | 온라인 |
| ConnectionLost | 0x16 | 둘 다 [?] |
| 호환되지 않는 프로토콜 버전 | 0x19 | 온라인 |
클라이언트의 연결되지 않은 패킷을 기다립니다.
클라이언트의 OpenConnectionRequestone 패킷을 기다립니다.
클라이언트의 OpenConnectionRequesttwo 패킷을 기다립니다.
클라이언트의 데이터 그램을 기다립니다.
연결되지 않은 패킷을 서버로 보냅니다.
OpenConnectionRequestone 패킷을 서버로 보내십시오.
OpenConnectionRequesttwo 패킷을 서버로 보내십시오.
데이터 그램을 서버로 보냅니다.
이 패킷은 서버가 온라인인지 여부를 결정하는 데 사용됩니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| OnlyReplyOnopenConnections | 부 | N/A | True로 설정된 경우 서버는 클라이언트의 서버 연결이 현재 열려있는 경우에만 회신을 보냅니다. 이를 통해 연결을 닫은 고객에게 응답을 보내는 것을 방지하는 데 도움이됩니다. 요청에 대한 결과 메시지 ID는 UnconnectedPingOpenConnections 입니다. False로 설정하면 식별자를 변경할 필요가 없습니다. |
| ID | UINT8 | N/A | 패킷의 고유 식별자 |
| 클라이언트 엔드 타임 | UINT64 | 빅 엔디언 | 대기 시간을 계산하는 데 사용되는 클라이언트 타임 스탬프 |
| 마법 | UINT8 [16] | N/A | 패킷을 식별하기위한 매직 시퀀스 |
| ClientGuid | UINT64 | 빅 엔디언 | 클라이언트를위한 고유 식별자 |
이 패킷은 연결되지 않은 핑 패킷에 대한 응답입니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| ID | UINT8 | N/A | 패킷의 고유 식별자 |
| 서버 엔드 타임 | UINT64 | 빅 엔디언 | 서버 타임 스탬프는 대기 시간을 계산하는 데 사용됩니다 |
| Serverguid | UINT64 | 빅 엔디언 | 서버의 고유 식별자 |
| 마법 | UINT8 [16] | N/A | 패킷을 식별하기위한 매직 시퀀스 |
| ResponseData | UINT16 스트링 | 빅 엔디언 | 일반적으로 서버 정보에 사용되는 응답 데이터 |
이 패킷은 클라이언트와 서버 간의 연결을 유지하는 데 사용됩니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| ID | UINT8 | N/A | 패킷의 고유 식별자 |
| 클라이언트 엔드 타임 | UINT64 | 빅 엔디언 | 대기 시간을 계산하는 데 사용되는 클라이언트 타임 스탬프 |
이 패킷은 연결된 핑 패킷에 대한 응답입니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| ID | UINT8 | N/A | 패킷의 고유 식별자 |
| 클라이언트 엔드 타임 | UINT64 | 빅 엔디언 | 핑에서 클라이언트 타임 스탬프 |
| 서버 엔드 타임 | UINT64 | 빅 엔디언 | 서버 타임 스탬프는 대기 시간을 계산하는 데 사용됩니다 |
이 패킷은 클라이언트와 서버 간의 핸드 셰이크 프로세스를 시작하는 데 사용됩니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| ID | UINT8 | N/A | 패킷의 고유 식별자 |
| 마법 | UINT8 [16] | N/A | 패킷을 식별하기위한 매직 시퀀스 |
| 프로토콜 버션 | UINT8 | N/A | 클라이언트가 지원하는 프로토콜 버전 |
| mtusize | 영역이있는 패드 | N/A | 클라이언트의 최대 전송 장치 (MTU) 크기 |
PAD-with-Zero를 사용하는 경우 MTU 크기에 읽기 위해 현재 읽기 위치와 28 (UDP 헤더 크기)을 추가하십시오. 쓰기의 경우 현재 버퍼 쓰기 위치 (또는 그 크기) + 28 (UDP 헤더 크기)과 현재 버퍼 크기로 MTU 크기를 빼도록하십시오. 패킷 버퍼를 확인하려면 크기가 28 (UDP 헤더 크기)과 현재 버퍼 크기인지 확인하십시오.
이 패킷은 열린 연결 요청 1 패킷에 대한 응답입니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| ID | UINT8 | N/A | 패킷의 고유 식별자 |
| 마법 | UINT8 [16] | N/A | 패킷을 식별하기위한 매직 시퀀스 |
| Serverguid | UINT64 | 빅 엔디언 | 서버의 고유 식별자 |
| ServerHassecurity | 부 | N/A | 서버에 보안이 필요한지 여부 |
| mtusize | UINT16 | 빅 엔디언 | 서버의 최대 전송 장치 (MTU) 크기 |
이 패킷은 개방형 연결 요청에 대한 응답으로 추가 보안 정보가 포함 된 하나의 패킷입니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| ID | UINT8 | N/A | 패킷의 고유 식별자 |
| 마법 | UINT8 [16] | N/A | 패킷을 식별하기위한 매직 시퀀스 |
| Serverguid | UINT64 | 빅 엔디언 | 서버의 고유 식별자 |
| ServerHassecurity | 부 | N/A | 서버에 보안이 필요한지 여부 |
| Hascookie | 부 | N/A | 패킷에 쿠키가 포함되어 있는지 여부 |
| 매력적인 여자 | UINT32 | 빅 엔디언 | 쿠키 가치 |
| ServerPublickey | UINT8 [294] | N/A | 암호화에 사용되는 공개 키 |
| mtusize | UINT16 | 빅 엔디언 | 서버의 최대 전송 장치 (MTU) 크기 |
이 패킷은 클라이언트와 서버 간의 핸드 셰이크 프로세스를 완료하는 데 사용됩니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| ID | UINT8 | N/A | 패킷의 고유 식별자 |
| 마법 | UINT8 [16] | N/A | 패킷을 식별하기위한 매직 시퀀스 |
| ServerAddress | UINT8 [7-29] | N/A | 서버 IP 주소 및 포트 콤보 |
| mtusize | UINT16 | 빅 엔디언 | 클라이언트의 최대 전송 장치 (MTU) 크기 |
| ClientGuid | UINT64 | 빅 엔디언 | 클라이언트를위한 고유 식별자 |
이 패킷은 클라이언트와 서버 간의 핸드 셰이크 프로세스를 완료하는 데 사용됩니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| ID | UINT8 | N/A | 패킷의 고유 식별자 |
| 마법 | UINT8 [16] | N/A | 패킷을 식별하기위한 매직 시퀀스 |
| 매력적인 여자 | UINT32 | 빅 엔디언 | 쿠키 가치 |
| challenge를 포함합니다 | 부 | N/A | 시스템에 핸드 셰이크 도전이 필요한지 여부 |
| 도전 | UINT8 [64] | N/A | 이 시스템은 챌린지 바이트를 핸드 웨이브 |
| ServerAddress | UINT8 [7-29] | N/A | 서버 IP 주소 및 포트 콤보 |
| mtusize | UINT16 | 빅 엔디언 | 클라이언트의 최대 전송 장치 (MTU) 크기 |
| ClientGuid | UINT64 | 빅 엔디언 | 클라이언트를위한 고유 식별자 |
참고 : OpenConnectionReplyOne 패킷에 보안이 있지만이 패킷에 도전이 포함되어 있지 않은 경우 클라이언트는 즉시 OpenConnectionRequestTWO 패킷에 도전이 없음을 서버에 알리기 위해 즉시 리모텔 systemRequirSpublickey 패킷을 보내야합니다.
연결 결과를 계산하는 자신만의 방법을 작성할 수 있지만 아래는 표준입니다.
연결 계산 :
bitwise and 아래 점검이 contains address 와 contains guid 확인하십시오.clientGuid 이미 다른 클라이언트 주소가있는 클라이언트와 연결되어 있으면 연결 상태를 3으로 설정하십시오.clientGuid 와 연결된 경우 연결 상태를 4로 설정하십시오.
ConnectionOutcome계산 한 후에는 1과 같은지 확인한 다음OpenConnectionReplyTwo패킷을 보내야합니다.
ConnectionOutcome이 0이 아닌 경우AlreadyConnected패킷을 보내십시오.
이 패킷은 열린 연결 요청 두 패킷에 대한 응답입니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| ID | UINT8 | N/A | 패킷의 고유 식별자 |
| 마법 | UINT8 [16] | N/A | 패킷을 식별하기위한 매직 시퀀스 |
| Serverguid | UINT64 | 빅 엔디언 | 서버의 고유 식별자 |
| ClientAddress | UINT8 [7-29] | N/A | 클라이언트 IP 주소 및 포트 콤보 |
| mtusize | UINT16 | 빅 엔디언 | 서버의 최대 전송 장치 (MTU) 크기 |
| 암호를 필요로합니다 | 조금 | N/A | 연결에 암호화가 필요한지 여부 |
| 암호화 키 | UINT8 [128] | N/A | 클라이언트의 암호화 키 - requiresEncryption 필드가 True로 설정된 경우에만 쓰여지거나 읽습니다. |
이 패킷은 클라이언트와 보안이 활성화되거나 비활성화 된 서버 간의 연결을 설정하는 데 사용됩니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| ID | UINT8 | N/A | 패킷의 고유 식별자 |
| ClientGuid | UINT64 | 빅 엔디언 | 클라이언트를위한 고유 식별자 |
| 클라이언트 엔드 타임 | UINT64 | 빅 엔디언 | 클라이언트가 연결하도록 요청했을 때의 타임 스탬프 |
| 선량 보안 | 부 | N/A | 연결에 보안이 필요한지 여부 |
| 클라이언트 기능 | UINT8 [32] | N/A | 클라이언트 인증 증명 |
| Doidentity | 부 | N/A | 패킷에 신분 증명이 필요한지 여부 |
| 신원 방송 | UINT8 [294] | N/A | 클라이언트 신원의 증거 |
참고 : 신원 증명이 유효하지 않고
doIdentityTrue로 설정된 경우ClientIdentityIsInvalid유형의 ID가있는RemoteSystemRequiresPublicKey패킷을 즉시 보내십시오.doIdentityFalse로 설정되어 있고 신원 증명이없는 경우ClientIdentityIsMissing유형의 ID가있는RemoteSystemRequiresPublicKey패킷을 보내십시오.
이 패킷은 클라이언트 인증 및 식별에 대한 공개 키 요청과 관련된 오류를 던지는 데 사용됩니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| ID | UINT8 | N/A | 패킷의 고유 식별자 |
| 타입 | UINT8 | N/A | 공개 키 요청 유형 |
| 이름 | ID |
|---|---|
| ServerPublicKeyismissing | 0 |
| ClientIdentityIsmissing | 1 |
| ClientIdentityIsinValid | 2 |
이 패킷은 서버가 보안이 필요하지 않지만 여전히 필수입니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| ID | UINT8 | N/A | 패킷의 고유 식별자 |
| ClientAddress | UINT8 [7-29] | N/A | 클라이언트 IP 주소 및 포트 콤보 |
| Serverguid | UINT64 | 빅 엔디언 | 서버의 고유 식별자 |
이 패킷은 서버에 가입하려는 시도 카운트가 일정 금액보다 높거나 (구현에 따라 다름) 클라이언트에 할당 된 주소가 포함되어 있지 않을 때 전송됩니다. OpenConnectionRequestOne 패킷을 보내기 전에 요구 사항이 충족되면 확인하고 보내는 것입니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| ID | UINT8 | N/A | 패킷의 고유 식별자 |
이 패킷은 클라이언트가 이미 연결되어있을 때 전송됩니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| ID | UINT8 | N/A | 패킷의 고유 식별자 |
| 마법 | UINT8 [16] | N/A | 패킷을 식별하기위한 매직 시퀀스 |
| ClientGuid | UINT64 | 빅 엔디언 | 클라이언트를위한 고유 식별자 |
이 패킷은 보안 활성화와의 연결 요청에 대한 응답입니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| ID | UINT8 | N/A | 패킷의 고유 식별자 |
| ClientAddress | UINT8 [7-29] | N/A | 클라이언트 IP 주소 및 포트 콤보 |
| ClientIndex | UINT16 | 빅 엔디언 | 클라이언트에 할당 된 고유 식별자 |
| ServerMachinEaddresses | 주소 [10] | N/A | 서버 로컬 머신 주소 |
| 클라이언트 엔드 타임 | UINT64 | 빅 엔디언 | 클라이언트를위한 타임 스탬프 |
| 서버 엔드 타임 | UINT64 | 빅 엔디언 | 서버의 타임 스탬프 |
이 패킷은 새 클라이언트가 서버에 연결하면 다른 모든 클라이언트에게 전송됩니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| ID | UINT8 | N/A | 패킷의 고유 식별자 |
| ServerAddress | UINT8 [7-29] | N/A | 서버 IP 주소 및 포트 콤보 |
| ClientMachinEaddresses | 주소 [10] | N/A | 클라이언트 로컬 머신 주소 |
| 클라이언트 엔드 타임 | UINT64 | 빅 엔디언 | 클라이언트를위한 타임 스탬프 |
| 서버 엔드 타임 | UINT64 | 빅 엔디언 | 서버의 타임 스탬프 |
이 패킷을 서버로 보내거나 수신 한 후에는 주기적으로 ConnectedPing 패킷을 보내어 연결을 유지해야합니다. 이 패킷은 본질적으로 "이봐, 나는 아직도 여기에 서버에 연결되어있다"고 말하는 방법이다. 서버는 또한 연결이 여전히 활성화되어 있음을 확인하기 위해 ConnectedPong 패킷을 다시 보냅니다. 이 Ping-Pong 프로세스는 비 활동 또는 네트워크 문제로 인해 연결이 타이밍을 방지하는 데 도움이됩니다.
이 패킷은 클라이언트가 서버에서 연결을 끊을 때 전송됩니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| ID | UINT8 | N/A | 패킷의 고유 식별자 |
이 패킷은 클라이언트에 대한 연결이 손실되면 전송됩니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| ID | UINT8 | N/A | 패킷의 고유 식별자 |
| ClientGuid | UINT64 | 빅 엔디언 | 클라이언트를위한 고유 식별자 |
| ClientAddress | UINT8 [7-29] | N/A | 클라이언트 IP 주소 및 포트 콤보 |
이 패킷은 클라이언트가 호환되지 않는 프로토콜 버전으로 서버에 연결하려고 시도 할 때 전송됩니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| ID | UINT8 | N/A | 패킷의 고유 식별자 |
| 프로토콜 버션 | UINT8 | N/A | 서버에서 지원하는 프로토콜 버전 |
| 마법 | UINT8 [16] | N/A | 패킷을 식별하기위한 매직 시퀀스 |
| Serverguid | UINT64 | 빅 엔디언 | 서버의 고유 식별자 |
이 패킷은 클라이언트와 서버간에 데이터를 전송하고 수신하는 데 사용됩니다. ValidDatagram, AckedDatagram 또는 NackedDatagram의 세 가지 유형 중 하나 일 수 있습니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| IsValid | 조금 | N/A | 항상 사실입니다 |
| Isack | 조금 | N/A | 사실이라면 패킷은 AckedDatagram입니다 |
| isnack | 조금 | N/A | 사실이라면 패킷은 NackedDatagram입니다 |
isAck과isNack모두 False 인 경우 패킷은 ValidDatagram입니다.
이 패킷은 서버가 데이터를 수신했음을 나타내는 ValidDatagram에 대한 응답입니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| 필요 대다 | 조금 | N/A | 사실이라면 패킷에는 b와 값이 포함됩니다 |
| 비 | 뜨다 | 빅 엔디언 | 사용되지 않습니다 |
| 처럼 | 뜨다 | 빅 엔디언 | 데이터 도착률 |
| 범위 | 범위 | N/A | 수신 된 범위 값의 배열 |
이 패킷은 서버가 예상 데이터를 모두 수신하지 않았 음을 나타내는 ValidDatagram에 대한 응답입니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| 범위 | 범위 | N/A | 받지 못한 범위 값의 배열 |
이 구조는 Ackeddatagram의 범위와 누락 된 범위의 NackedDatagram을 나타내는 데 사용됩니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| 크기 | UINT16 | 빅 엔디언 | 배열의 범위 수 |
| 싱글 | 부 | N/A | Min이 Max와 같으면 True로 설정됩니다. |
| 최소 | UINT24 | 작은 엔디언 | 범위의 최소값 |
| 맥스 | UINT24 | 작은 엔디언 | 범위의 최대 값 - 단일이면 쓰여지지 않습니다. |
이 패킷은 클라이언트와 서버간에 데이터를 전송하고 수신하는 데 사용됩니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| ISPACKETPAIR | 조금 | N/A | 사실이라면 패킷은 두 개의 관련 패킷 중 하나입니다. |
| iscontinoussend | 조금 | N/A | 사실이라면 패킷은 연속 전송 패킷입니다 |
| 필요 대다 | 조금 | N/A | 사실이라면 패킷에는 b와 값이 포함됩니다 |
| rangenumber | UINT24 | 작은 엔디언 | 데이터 그램의 시퀀스 번호 |
| 캡슐 | Datagramcapsule [] | N/A | 패킷의 캡슐 배열 |
손상된 배열 채널 확인 : (유효한 데이터 그램은`시퀀싱되고 배열되어야합니다 (ACK 영수증 없음))
arrangmentChannel 더 크거나 2 ^ 5 인 배열 스트림의 수와 같다면 (필요한 것을 건너 뛰고 수행).
배열 최대 값의 모든 유효한 데이터 그램 배열 유형은 배열 스트림의 수이며 더 크거나 같아야합니다.
수신 된 데이터 그램에서 구멍 수 찾기 : (유효한 데이터 그램은 Reliable or in sequence 대로 진행되기 전에)
Reliable or in sequence 유효한 데이터 그램에서 구멍 수를 확인해야하며 그 이유는 주문을 확인해야하며 유효한 데이터 그램이 누락되었거나 잘못된 rangeNumber 가 전송에 사용되었는지 또는 다른 이유가 있는지 확인하는 역할을합니다.
receivedPacketsBaseIndex : 유효한 데이터 그램 Reliable or in sequence 하는 경우에만 증가합니다.
receivedPacketQueue : 그것은 유효한 데이터 그램의 rangeNumber 목록의 키로 저장하는 것이며 값은 데이터 그램이 아니라는 것이 사실 일 수 있지만 아래에 언급 될 일부 코드를 충족 한 후에는 (허위로 우리가 성공적으로 이해하지 못했다는 것을 의미합니다) DS_Queue 입니다.
구멍 수를 찾으려면 수신 된 파크 receivedPacketsBaseIndex 를 사용하여 현재 수신 된 유효한 데이터 그램의 rangeNumber 빼고 구멍 수가 없을 때마다 해당 속성이 증가합니다 ( Reliable or in sequence receivedPacketsBaseIndex 만 증가).
receivedPacketQueue 에서 제거하고 receivedPacketsBaseIndex 를 추가 (사전) 증분으로 추가하십시오.uint24 의 최대 값보다 크면 1 bitwise right shifted 경우 복제 된 패킷입니다 (필요한 것을 건너 뛰고 수행하십시오).receivedPacketQueue 크기보다 작은 경우receivedPacketQueue 의 인덱스/키이고 거짓과 같지 않은 경우, receivedPacketQueue 의 홀 카운트의 키를 교체하여 값이 값이 값과 같다는 키를 교체하여 구멍을 채우십시오.언급 된 이러한 조건이 충족되지 않았다면 다음과 같이
bitwise and uint32 최대 값이 필요한 경우 최대 값)이 receivedPacketQueue 크기보다 크면 대기열에서 실제 값을 푸시하여 채우십시오. 그런 다음 루프를 생성하고 receivedPacketQueue 크기가 0보다 크고 receivedPacketQueue 의 첫 번째 값이 false인지 확인한 다음 receivedPacketQueue 의 마지막 요소를 제거한 다음 receivedPacketsBaseIndex 를 증가시킬 수 있습니다.
그 후에는 유효한 데이터 그램을 정상적으로 처리 할 수 있습니다.
이 구조는 ValidDatagram의 캡슐을 나타냅니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| 신뢰할 수 있음 | 3 비트 | 빅 엔디언 | 사용 된 신뢰성의 유형 |
| issegmented | 조금 | N/A | 사실이라면 패킷이 분할됩니다 |
| 크기 | UINT16 | 빅 엔디언 | 버퍼 필드의 크기는 비트로 아래로 내려갑니다 |
| Reliablecapsuleindex | UINT24 | 작은 엔디언 | 신뢰할 수있는 패킷에 사용되는 색인 (이를위한 신뢰성을 사용한다는 의미) |
| 시퀀스 캡슐 인덱스 | UINT24 | 작은 엔디언 | 시퀀싱 된 패킷에 사용되는 색인 (이를위한 신뢰성을 사용한다는 의미) |
| 준비 | 캡슐 렌즈 | N/A | 시퀀싱 및 배열 패킷에 사용되는 캡슐 배열 (이를위한 신뢰성을 사용한다는 의미) |
| 분절 | 캡슐 세그먼트 | N/A | 캡슐이 분할 될 때 사용되는 캡슐 세그먼트 |
| 완충기 | 완충기 | N/A | 데이터가 포함 된 버퍼 데이터 네트워크를 통해 전송되기를 원했습니다. |
이 구조는 ValidDatagram에서 캡슐의 배열을 나타냅니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| 배열 capsuleindex | UINT24 | 작은 엔디언 | 배열 된 캡슐의 색인 |
| 배열 채널 | UINT8 | N/A | 배열에 사용되는 채널 |
이 구조는 ValidDatagram에서 캡슐의 분할을 나타냅니다.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| 크기 | UINT32 | 빅 엔디언 | 세그먼트의 크기 |
| ID | UINT16 | 빅 엔디언 | 세그먼트와 관련된 고유 식별자 |
| 색인 | UINT32 | 빅 엔디언 | 세그먼트의 색인 |
RAKNET에 전송 된 각 데이터 그램에는 데이터를 프로토콜에 의해 처리하는 방법을 지정하는 신뢰성 TypeID가 할당됩니다. 다음 표는 사용 가능한 신뢰성 타입 및 해당 속성을 나열합니다.
| 이름 | ID | 신뢰할 수 있습니다 | 배열됩니다 | 시퀀싱됩니다 | 특성/기능 |
|---|---|---|---|---|---|
| 신뢰할 수 없는 | 0 | 아니요 | 아니요 | 아니요 | 이 신뢰성 TypeID는 대상에 도착할 것이라는 보장없이 데이터 그램을 보냅니다. 그들은 특정 순서로 또는 전혀 배달되는 것을 보장하지 않습니다. |
| 틀림 없다 | 1 | 아니요 | 예 | 예 | 이 신뢰성 TypeID는 대상에 도착할 것이라는 보장없이 데이터 그램을 보냅니다. |
| 믿을 수 있는 | 2 | 예 | 아니요 | 아니요 | 이 신뢰성 TypeID는 보내진 순서대로 전달되는 데이터 그램을 보냅니다. 데이터 그램이 손실되면 Raknet은 수신기가 인정받을 때까지 재전송합니다. |
| 신뢰할 수 있습니다 | 3 | 예 | 예 | 아니요 | 이 신뢰성 TypeID는 보내진 순서대로 전달되는 데이터 그램을 보냅니다. 데이터 그램이 손실되면 RAKNET은 인정되지 않은 모든 데이터 그램을 재전송하지 않습니다. |
| 신뢰할 수 있습니다 | 4 | 예 | 예 | 예 | 이 신뢰성 TypeID는 보내는 순서대로 전달되는 데이터 그램을 보내고 순차적으로 전달되도록합니다. |
| 신뢰할 수 없음 | 5 | 아니요 | 아니요 | 아니요 | 이 신뢰성 TypeID는 대상에 도착할 것이라는 보장없이 데이터 그램을 보냅니다. 그러나 수신기는이 데이터 그램을 받으면 승인 영수증을 보냅니다. |
| 신뢰할 수 있습니다 | 6 | 예 | 아니요 | 아니요 | 이 신뢰성 TypeID는 보증 된 순서대로 전달되는 데이터 그램을 보냅니다. 수신기는이 데이터 그램을 받으면 승인 영수증을 보냅니다. |
| reliablearrangedwithackreceipt | 7 | 예 | 예 | 아니요 | 이 신뢰성 TypeID는 전송 된 순서대로 전달되는 데이터 그램을 보냅니다. |
여기서 문서의 다른 장소에서 사용되는 모든 신뢰성 정의를 찾을 수 있습니다.
Sequenced 되고 신뢰할 수있는 정렬되고 ACK 수용체로 신뢰할 수있는 경우입니다.RAKNET은 선택적 반복 재전송을 사용하여 데이터 그램의 안정적인 전달을 보장합니다. 데이터 그램이 전송되면 시퀀스 번호가 할당됩니다. 특정 시간 초과 기간 내에 데이터 그램이 인정되지 않은 경우 Raknet은 동일한 시퀀스 번호를 사용하여 데이터 그램을 다시트를 다시 작성합니다. 수신기가 동일한 시퀀스 번호의 중복 데이터 그램을 수신하면 해당 시퀀스 번호를 이미 인정 했으므로 폐기 할 수 있습니다.
Ackqueue와 Nackqueue는 어떤 데이터 그램이 인정되었는지, 그렇지 않은지 추적하는 데 사용됩니다. Ackqueue는 성공적으로 인정 된 데이터 그램 시퀀스 번호 목록을 저장하는 반면 Nackqueue는 인정되지 않았고 재전송해야 할 데이터 그램 시퀀스 번호 목록을 저장합니다. 이미 인정 된 시퀀스 번호로 데이터 그램이 수신되면 폐기 할 수 있습니다.
PacketPair는 Raknet이 데이터 그램 레트라 런스의 효율성을 향상시키기 위해 사용하는 기술입니다. 데이터 그램이 승인되면 Raknet은 다음 데이터 그램을 순서대로 보냅니다. 이를 통해 수신기는 다음 데이터 그램을 즉시 처리하여 대기 시간을 줄이고 처리량을 향상시킬 수 있습니다.
ContinuousSend는 RAKNET의 기능으로, 승인을 기다리지 않고 데이터 그램을 지속적으로 전송할 수 있습니다. 이는 일부 경우 성능을 향상시킬 수 있지만 발신자는 다음 데이터 그램을 보내기 전에 피드백을 기다리지 않기 때문에 패킷 손실 및 재전송으로 이어질 수 있습니다.
Raknet은 재 조립 메커니즘을 사용하여 순서대로 수신 할 수있는 세그먼트 된 데이터 그램을 재구성합니다. 데이터 그램이 세그먼트화되면 각 세그먼트에는 고유 식별자가 할당됩니다. 수신기가 세그먼트를 수신하면 동일한 식별자가있는 모든 세그먼트가 수신 될 때까지 버퍼링됩니다. 모든 세그먼트가 접수되면 원래 데이터 그램으로 다시 조립됩니다.
Flow Control은 발신자와 수신기 간의 데이터 전송 속도를 관리하는 데 사용되는 RAKNET 메커니즘입니다. 수신기가 처리 할 수있는 속도로 들어오는 데이터를 처리 할 수 있도록하여 수신기의 버퍼를 압도적이거나 넘치지 않도록합니다. 흐름 제어는 발신자의 전송 속도와 수신기의 처리 기능 간의 균형을 유지하여 통신의 전반적인 효율성과 안정성을 최적화합니다.
혼잡 관리자는 혼잡 제어를 보유하고 있으며, 건너 뛰는 범위 번호를 확인하여 Nacks 및 기타 물건을 보냅니다.
TODO : 문서를 추가하십시오
정체 제어는 데이터 전송 속도 균형을 유지하여 네트워크 혼잡을 방지하는 데 사용되는 RAKNET 기술입니다. TCP 혼잡 제어, 패킷 삭제, 속도 제한, 트래픽 성형, QOS 및로드 밸런싱과 같은 기술이 사용됩니다. 이러한 기술은 RAKNET에서 안정적인 데이터 전달 및 효율적인 전송을 보장합니다.
Raknet의 세분화는 큰 메시지를 더 작은 세그먼트로 나누어 데이터 전달을 향상시킵니다. 위치와 크기를 나타내는 헤더가있는이 세그먼트는 수신기 끝에서 성공적인 재 조립을 보장합니다. 버퍼 크기를 최대 전송 장치 (MTU) 크기와 비교함으로써 버퍼가 MTU를 초과하면 전송을 위해 세그먼트로 분할됩니다. Raknet 의이 메커니즘은 데이터 손실을 방지하고, 큰 페이로드를 관리하며, 네트워크 응용 프로그램에서 안정적인 전송을 보장합니다.
"B"는 네트워크 링크를 통해 초당 전송할 수있는 링크 용량 또는 최대 데이터 양을 나타냅니다. 링크 용량은 네트워크 인프라, 네트워크 구성 및 사용 가능한 리소스를 포함한 여러 요소에 의해 결정됩니다. 플로트 값을 사용함으로써 네트워크 용량은보다 정확하고 정확하게 표현되어 가용 리소스를 더 잘 활용할 수 있습니다.
"AS"는 데이터 도착률을 나타내며, 이는 데이터가 발신자가 생성하고 전송하는 속도입니다. 플로트 값을 사용하면 도착률을보다 정확하게 표현할 수 있으며, 이는 애플리케이션 요구 사항 및 네트워크 조건에 따라 달라질 수 있습니다. 도착률을 링크 용량과 비교함으로써 발신자는 정체 또는 성능 저하를 일으키지 않고 네트워크 링크를 통해 전송 될 수있는 데이터의 양을 결정할 수 있습니다.
캡슐의 크기를 결정하려면 다음 단계를 따라갈 수 있습니다.
reliableCapsuleIndex 수있는 경우, 바이트를 3 단계 씩 증가 시키십시오.sequencedCapsuleIndex 나타내는 3 단계만큼 바이트를 증가시킵니다.arrangedCapsuleIndex 의 경우 바이트를 3 단계로, 그리고 arrangementChannel 의 경우 1 단계로 배열하십시오.size 의 4 단계, id 의 경우 2 단계, 세그먼트 index 의 4 단계 씩 바이트를 증가시킵니다. userpacketenum id는 0x86 이며 사용자 정의 패킷 ID를 사용하는 시작의 시작을 나타냅니다.
권장되는 것은 완료된 구현이 있다는 점을 고려하여 PacketAggregator 작성하고 보내고받는 것이 좋습니다.
다음과 같이 선택한 ID를 넣을 수 있습니다. UserPacketEnumID + 자신의 ID ( UserPacketEnumID uint8 limit 능가하지 않아야합니다).
예를 들어 : UserPacketEnumID + 22 = 0x9c
PacketAggregator 무엇인지 보여주는 간단한 패킷 구조.
| 필드 | 유형 | 엔지니어 | 메모 |
|---|---|---|---|
| ID | UINT8 | N/A | 패킷의 고유 식별자 |
| 압축 알로리즘 | UINT8 | 압축 알고리즘 [없음, OpenSSL, Zlib, GZIP, Snappy, 무엇이든] | |
| 스트림 | 완충기[] | 패킷 스트림의 배열 (스트림 어레이의 각 요소는 인코딩 된 패킷 버퍼를 나타내고 compressionAlgorithm 에서 해독 될 패킷 버퍼를 나타냅니다) |
그런 다음 유효한 데이터 그램 캡슐/S 버퍼로 보내드립니다.
비 Raknet 패킷을 보내려면 먼저 캡슐 버퍼 크기가 MTU 크기 마이너스 2보다 큰지 비교하여 세분화가 필요한지 결정하십시오. DataGram의 데이터 헤더 바이트 길이의 경우 3 번 더하기 1 (DataGram의 데이터 헤더 바이트 길이) 및 보안이 사용되는 경우 11을 빼십시오. 그런 다음 주어진 값을 캡슐 크기로 빼십시오. 세분화가 필요한 경우 캡슐 스트림을 segemnt로 전송하기 위해 데이터 그램 큐에 추가하십시오. 분할이 필요하지 않으면 큐에 직접 추가하십시오. 세그먼트 된 패킷은 신뢰할 수 없어야합니다. 그들이 있다면, 모든 패킷 부품의 성공적이고 주문한 배송을 보장하기 위해 신뢰할 수있는 패킷으로 변환합니다.
파트로 분할하는 방법 :
캡슐 크기와 캡슐 버퍼 크기를 얻은 다음 캡슐 버퍼 크기보다 큰지 확인하고 정의하는 크기를 얻습니다.
to get the count of how many segments is needed to be made: subtract the capsule buffer size with 1 then divide it with the size that you used to check if is greater than the capsule buffer size then sum them with 1 (not two times) or you can ceil instead of subtracting 1 and adding 1 at the end
then define a current segment index outside the loop and is 0 by default
then do a loop that will use the count of how many segments then the segmentation process will start:
after that define a variable representing start offset and it is equals to current segment index multiplied by the size that you used to check if is greater than the capsule buffer size
after that define a variable representing bytes to send that is equals to capsule buffer size subtracted by start offset
check if bytes to send is greater than the size that you used to check if is greater than the capsule buffer size and if true set the bytes to send value to the size that you used to check...
after that create a new variable representing the end offset
check if the bytes to send is not the size that you used to check if is greater than the capsule buffer size then set the end offset to the capsule buffer size subtracted by the current segment index multiplied by the size that you used to check if is greater than the capsule buffer size
if the check fails then the end offset will be the bytes to send
after that slice the capsule buffer with the start offset and end offset then you can do the feilds in the capsule.
you will need an array that has the capsules that contains the segments that will then be sent in queue.
the segment id will be the sender last segment id property that will increment outside the loop every time.
Here are a list of resources to help you better understand the RakNet protocol: