Skip to content

Commit 0d67579

Browse files
committed
rudp 추가
1 parent c8bc014 commit 0d67579

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+5542
-0
lines changed
2.48 MB
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# GGPO
2+
3+
- [격투 게임의 온라인 대전 랙을 줄여주는 기술 "GGPO"가 MIT 라이센스로 무료 제공](https://docs.google.com/document/d/e/2PACX-1vQKfybQo9jvfExu9U8bqDhM9s_f6sB31w6sVYnzlTvrhM9wPpJOS_rT_48kLYkKtsppPeE6o00Ut4qC/pub )
4+
- [Github 저장소의 README.md](https://docs.google.com/document/d/e/2PACX-1vTchkKuUNEN25ielPHMoGcndJg_LXNgnaRRd3dq9mexa9IaeopSQ2UBfhXv-wEtEl01fV61P7m0J5y_/pub )
5+
- [개발자 가이드](https://docs.google.com/document/d/e/2PACX-1vRziQRn7COow5T1yornPH7CVyI8G2LkGwv-7Z8K4_n9vesHXsRIPhGDqgHaYOkPzNtCepguRDx5RPzC/pub )
6+
7+
8+
9+
10+
## Github
11+
- https://github.com/pond3r/ggpo

udp_network_rudp/README.md

+196
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
# Reliable UDP(RUDP) 설명과 코드 분석
2+
3+
# 설명
4+
- PC 온라인 게임 시대에는 P2P 게임에서 사용할 목적으로 이 기술을 사용.
5+
- 그러나 모바일 시대에서는 PC에 비해 좋지 않은 네트워크 환경 때문에 C/S 환경에서 사용한다.
6+
- Reliable UDP는 이름 대로 UDP를 사용한다.
7+
- 여기서 네트워크 프로그래밍의 기초인 UDP, TCP 차이는 설명하지 않음.
8+
9+
## RUDP의 특징
10+
- UDP를 사용하지만 TCP처럼 신뢰성(전송 보장과 패킷 순서)을 가진다.
11+
- 애플리케이션에서 수신 여부와 순서를 보정해야 한다.
12+
13+
## RUDP의 패킷 타입
14+
1. 일반적인 UDP 패킷 전송(신뢰성 없음)
15+
2. 전송은 보장, 그러나 순서는 보장 하지 않음
16+
3. 전송 보장, 순서 보장
17+
18+
19+
<br>
20+
21+
**네트워크 성능과 구현의 쉬움 순서는 1 > 2 > 3**
22+
23+
<br>
24+
25+
## 패킷 구성
26+
- 전송 타입: 앞의 패킷 타입
27+
- 패킷의 고유 넘버: 수신쪽에서 순서를 판단하기 위해 보내는쪽에서 순서대로 증가하는 번호를 사용한다.
28+
- 에러 검출: crc 코드 등을 사용하여 패킷에 변조가 없는지 조사
29+
- 패킷 데이터: 송신자가 보낼 실 데이터
30+
31+
<br>
32+
33+
## RUDP 패킷 보내기
34+
![](/resource/00001.PNG)
35+
![](/resource/00002.PNG)
36+
![](/resource/00003.PNG)
37+
![](/resource/00004.PNG)
38+
39+
<br>
40+
41+
## remote의 정보 관리
42+
```
43+
len = recvfrom(socket, buffer, sizeof(buffer),
44+
0, &addr, &addrlen);
45+
46+
packet = packet_decode(buffer, len);
47+
48+
con = find_connect(packet);
49+
if (con == NULL) {
50+
con = connected(addr, buffer, len);
51+
}
52+
53+
if (con != NULL) {
54+
con->recv_packet(packet);
55+
}
56+
```
57+
58+
59+
## 패킷 고유 번호
60+
고유하게 1씩 증가하는 경우
61+
```
62+
if (packet->ackcnt <= recnt_ackcount ||
63+
find_recvpacket_id(recnt_ackcount) {
64+
return ; // 이미 처리한 패킷
65+
}
66+
67+
if (recnt_ackcount+1 == packet->ackcnt)
68+
{
69+
recnt_ackcount+=1;
70+
while(find_recvpacket_id(recnt_ackcount))
71+
{
72+
remove_recvpacket_id(recnt_ackcount);
73+
recnt_ackcount++;
74+
}
75+
}
76+
else
77+
{
78+
insert_recvpacket_id(recnt_ackcount);
79+
}
80+
```
81+
82+
83+
## 패킷 보내기
84+
```
85+
int rudp_connect::send(char * buff, int len, udp_packet_type type)
86+
{
87+
rudp_packet packet;
88+
int len;
89+
len = encode_packet(&packet, buff, len, type);
90+
if (ISRECHABLE(type))
91+
store_send_packet(&packet);
92+
return sendto(packet, len, & m_addr);
93+
}
94+
```
95+
96+
97+
## 패킷 받기 처리
98+
```
99+
void rudp_connect::recv(char * buff, int len)
100+
{
101+
rudp_packet packet;
102+
int len;
103+
len = decode_packet(&packet, buff, len);
104+
if (ISINVALIDEPACKET(packet))
105+
return;
106+
switch(packet.type)
107+
{
108+
case udp_packet_type_a :
109+
parse_game_packet(packet.data, packet.len);
110+
break;
111+
case udp_packet_type_b :
112+
send_ackpacket(&packet);
113+
if (ISOLDPACKET(packet.ackcnt) == false)
114+
{
115+
update_recv_packetcount(packet.ackcnt);
116+
parse_game_packet(packet.data, packet.len);
117+
}
118+
break;
119+
case udp_packet_type_c :
120+
send_ackpacket(&packet);
121+
if (ISOLDPACKET(packet.ackcnt) == false)
122+
{
123+
update_recv_packetcount(packet.ackcnt);
124+
if (ISRECENTPACKET(packet.seqcnt) == true)
125+
{
126+
parse_game_packet(packet.data, packet.len);
127+
for(i=packet.seqcnt+1; 1; i++)
128+
{
129+
p = find_recv_packet(i)
130+
parse_game_packet(p->data, p->len);
131+
remove_recv_packet(p);
132+
}
133+
update_recv_packet_seqcnt(i);
134+
} else
135+
store_recv_packet(&packet, packet.seqcnt);
136+
} break;
137+
case udp_packet_ack :
138+
remove_send_packet(packet.ackcnt);
139+
break;
140+
...
141+
}
142+
}
143+
```
144+
145+
<br>
146+
147+
## 데이터그램을 보낼 때 해야할 일
148+
- 데이터그램의 ID를 부여한다. 이는 보낼 때마다 +1씩 증가시키는 방법으로 처리하면 된다.
149+
- 데이터그램을 보낸다.
150+
- 데이터그램에 대한 인증을 받지 못했을 경우, 다음에 전송해야하는 시간을 기록해둔다.
151+
- 데이터그램에 대한 인증을 받지 못했을 경우, 전송을 시도할 최대 횟수를 기록해둔다.
152+
- 데이터그램을 보냈지만, 아직 인증받지 못한 데이터그램의 리스트에다가 집어넣어둔다.
153+
154+
155+
## 데이터그램을 받았을 때 해야할 일
156+
- 데이터그램이 이미 한번 실행했던 데이터그램이 아닌지 검사한다. 이는 중간에 빠진 데이터그램의 리스트와 현재까지 도착한 데이터그램ID의 최대값을 이용해서 이루어진다.
157+
- 이미 한번 실행했던 것이라면 그냥 무시하고, 아니라면 정상적으로 실행한다.
158+
- 현재까지 도착한 데이터그램ID의 최대값과 중간에 빠진 데이터그램의 리스트를 갱신한다.
159+
- 데이터그램을 "정상적으로 실행했지만, 송신측에 알려주지 않은 리스트"에다가 등록한다.
160+
- 만일 데이터그램이 수신측이 보내온 인증 데이터그램이라면 보냈지만, 아직 인증받지 못한 데이터그램의 리스트에 있는 해당하는 데이터그램들을 삭제해준다.
161+
162+
163+
## 주기적으로 처리해야할 일
164+
- 정상적으로 실행했지만, 송신측에 알려주지 않은 리스트에 데이터그램ID가 들어있다면 이를 송신측에게 송신한다. (이 데이터그램 역시 데이터그램을 보내는 것이므로, 데이터그램을 보낼 때 해야할 일들을 차례로 수행한다.)
165+
- 보냈지만, 아직 인증받지 못한 데이터그램의 리스트를 검색하면서 재전송해야하는 데이터그램이 있다면 재전송한다. (재전송할 때마다 다음에 전송해야하는 시간과 전송 시도 횟수를 갱신해야한다.)
166+
- 최대 재전송 횟수를 초과한 데이터그램은 삭제해버린다. (끝까지 전송되지 않는 데이터그램이 결국 생길 수 있다.)
167+
168+
169+
## 타임 아웃에 의한 재전송
170+
타임 아웃과 재전송은 단순히 일정한 타임 아웃 시간을 사용하는 것이 아니라 네트워크의 성질이나 상태, 부하 등을 고려해야 한다.
171+
- 패킷이 송신자에서 수신자에게 도착해서 다시 돌아올 때까지 왕복 시간(Round-Trip Time:왕복 시간)의 현 시점의 추계치를 통계적으로 구하고, 유지한다. 이 추계치를 토대로 패킷을 네트워크로 보내어, 이것이 너무 빨라서 네트워크를 독점적으로 채우지 않도록 한다.
172+
- 다음 재시도까지의 대기 시간을 계산할 때 "지수적 백 오프"를 사용하여 오류가 자꾸 반복될 때마다 다음 재전송까지 시간이 지수적으로 늘어난다. 이렇게하면, 네트워크 상의 패킷 수가 점점 줄어드니 다음 재전송이 잘 나갈 가능성이 높아진다.
173+
174+
175+
## RUDP 주의할 점
176+
- 만약 특정 패킷이 계속 전달되지 않을 경우 포기하지 않고 계속 시도하면 네트워크가 멈춘 것 같은 상태가 된다.
177+
- 특정 횟수 이상 실패하면 포기하고 다음 패킷을 보낼 수 있도록 예외 처리가 잘 되어 있어야 한다.
178+
179+
180+
## 외부 글
181+
- [Reliable UDP 구현](./Reliable_UDP_구현.pdf) [출처](http://www.slideshare.net/noerror/rudp)
182+
- [Reliable UDP 구현과 활용](./Reliable_UDP_구현과_활용.pdf) [출처](http://egloos.zum.com/choiwonwoo/v/924906)
183+
- [Reliable 구현](./Reliable_udp_chikicon.pdf) [출처](http://blog.naver.com/chikicon/60036633811)
184+
185+
186+
<br>
187+
<br>
188+
<br>
189+
190+
191+
# 참고 글
192+
- [Unity Technologies의 온라인 대전 FPS 게임 구현을 조사해 보았다](https://docs.google.com/document/d/e/2PACX-1vQVBLOLuCeapeZTjOUxNVNXO3pxAUhr1r7k4qQUAP-CLGaVqZEnNecPWGvCI8YqeZ9MJwL_mw8STCrx/pub )
193+
- [〈카트라이더〉 0.001초 차이의 승부 - 300km/h 물체의 네트워크 동기화 모델 구현기](http://ndcreplay.nexon.com/NDC2019/sessions/NDC2019_0002.html#c=NDC2019&t%5B%5D=%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D&p=3 )
194+
- [QUIC은 데이터 손실시 처리 대기를 어떻게 최소화할까?](https://docs.google.com/document/d/e/2PACX-1vSeUKRkoEVJ0hRTj8Gik4tqclh47p56yJlwjL-7F3JTvvlQ3cJl2dD3RbhnDdANSm_YxTqtaouMvi3w/pub )
195+
- [[draft-ietf-sigtran-reliable-udp](http://crowback.tistory.com/category/Programming/Protocol%20-%20RUDP )
196+
285 KB
Binary file not shown.
Binary file not shown.
866 KB
Binary file not shown.

udp_network_rudp/Rollback_Network.md

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Rollback Network 서버 동기화 되감기
2+
3+
- [온라인 게임에서는 서로의 위치가 멀리 떨어져 있어도(일본과 브라질 정도) 왜 빠르게 동기화할 수 있을까? 어떻게 통신하고 있을까?](https://docs.google.com/document/d/e/2PACX-1vSFnUdI5AiTRI43RDnh9V65qKyDK8tQYFSX4GQWsc6YzZHli4Xo7t5ufW4M6Zt0aOMbcPdTb_vO1FEp/pub )
4+
- 格闘ゲームのネット対戦を快適にするロールバック方式とは?](https://flash-m.jp/gaming-environment/roleback)
5+
- オンライン対戦のラグと入力遅延の違いをストリートファイタ-Vを例に解説](https://flash-m.jp/game-introduction/%e3%82%b9%e3%83%88%ef%bc%95/post-1532 )
6+
- 『GUILTY GEAR XX ΛCORE PLUS R』にてオンライン対戦の遅延を改善する“期待の技術”テスト開始。ほぼ遅延なしの対戦を実現する「ロールバックネットコード」とは何なのか? https://automaton-media.com/articles/newsjp/20201031-141954/
7+
8+
9+
## Pong을 통한 롤백 동기화 분석
10+
- 설명: https://www.youtube.com/watch?v=j3eQNm-Wk04
11+
- https://github.com/zeliard/PongRewind
12+
Binary file not shown.

udp_network_rudp/open_source.md

+164
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
# C++
2+
3+
## cloudwu/rudp
4+
- https://github.com/cloudwu/rudp
5+
6+
7+
## C++ UDP Networking Library
8+
- https://github.com/jivibounty/Packet
9+
- Packet-master.zip
10+
- Visual C++ 지원.
11+
- 서버/클라이언트.
12+
- 이런 저런 기능이 많이 구현 되어 있음.
13+
- 설계 측면에서는 좀 바꾸고 싶음.
14+
15+
16+
## tinynet
17+
- https://github.com/RandyGaul/tinyheaders
18+
- header only 라이브러리. 여기에 RUDP 코드가 있음(1개의 헤더 파일)
19+
- 너무 많이 복잡하지 않은 듯.
20+
- 그러나 사용 예제가 없어서 사용 방법은 좀 헷갈리듯
21+
22+
23+
## A UDP-Only Winsock RIO C++ Network Library
24+
- https://github.com/kklouzal/PeerNet
25+
26+
27+
## netcode.io : A simple protocol for creating secure client/server connections over UDP
28+
- https://github.com/networkprotocol/netcode.io
29+
30+
31+
## reliable.io. A simple reliability layer for UDP-based protocols
32+
- https://github.com/networkprotocol/reliable.io
33+
34+
35+
## Launch of libyojimbo
36+
- http://gafferongames.com/2016/07/21/launch-of-libyojimbo/
37+
- https://github.com/networkprotocol/yojimbo
38+
39+
40+
## enet(UDP 네트워크 라이브러리)
41+
- https://github.com/lsalzman/enet
42+
- http://enet.bespin.org/
43+
44+
45+
## NanoSockets
46+
- https://github.com/nxrighthere/NanoSockets
47+
48+
49+
## ValveSoftware/GameNetworkingSockets. Reliable & unreliable messages over UDP. Robust message fragmentation & reassembly. Encryption.
50+
- https://github.com/ValveSoftware/GameNetworkingSockets
51+
52+
53+
## KCP
54+
- UDP 베이스의 스루풋을 희생하고 저 지연을 위한 프로토콜(A Fast and Reliable ARQ Protocol)
55+
- https://github.com/skywind3000/kcp
56+
57+
58+
59+
<br>
60+
61+
62+
# C#
63+
64+
## unity_rudp
65+
- https://github.com/linuxaged/unity_rudp
66+
- unity_rudp-master.zip
67+
- 구현은 1개의 파일로 되어 있음.
68+
- C#으로 유니티3D에서 사용하는 것을 전제로.
69+
- 테스트 코드도 있음.
70+
- `/source_code/unity_rudp`에 코드를 정리해 놓았다
71+
72+
73+
## houshuo/RUDP
74+
- https://github.com/houshuo/RUDP
75+
- RUDP-master.zip
76+
- 1개의 파일로 되어 있음.
77+
- 코드 분석이 쉬울 듯.
78+
- `/source_code/RUDPTest`에 코드를 정리해 놓았다
79+
80+
81+
## SharpRUDP
82+
- https://github.com/whl0070179/SharpRUDP
83+
- `/source_code/SharpRUDP`에 코드를 정리해 놓았다
84+
- Thread-safe.
85+
- Channel-based communication.
86+
- Keeps the connection alive using tiny keepalive packets.
87+
- Retransmission of unacknowledged packets in the next send/reset iteration.
88+
- Different serialization options (JSON and Binary. Binary is default, as it's WAY faster than JSON!)
89+
- Packet data can be in JSON format, so the protocol can be ported to other languages (Node.js anyone?) without much issue.
90+
- Pure concise, clean C# code. Avoids C++ wrappers and obscure BS. Most of the code is in RUDPConnection.cs and RUDPChannel.cs and they're < 700 lines long together!.
91+
- Long data can be sent and will be retrieved sequentially, while keeping packet size to a safe MTU value (8Kb, since Android has 16Kb and Windows has 64Kb, safe spot is 8Kb). However, it will reserve 20% of that size for packet data just in case.
92+
93+
94+
## nxrighthere/ENet-CSharp
95+
- https://github.com/nxrighthere/ENet-CSharp
96+
97+
98+
## FinalSpeed-RUDP-CSharp
99+
- https://github.com/wspl/FinalSpeed-RUDP-CSharp
100+
- FinalSpeed-RUDP-CSharp-master.zip
101+
- 구현이 잘 되어 있는듯.
102+
103+
104+
## - KCP
105+
- UDP 베이스의 스루풋을 희생하고 저 지연을 위한 프로토콜(A Fast and Reliable ARQ Protocol)
106+
- https://github.com/KumoKyaku/KCP
107+
108+
109+
## Netcode.IO.NET
110+
- https://github.com/KillaMaaki/Netcode.IO.NET
111+
112+
113+
## **LiteNetLib**
114+
- [LiteNetLib - Lite reliable UDP library for Mono and .NET](https://github.com/RevenantX/LiteNetLib )
115+
- [LiteNetLibとMessagePackで行うリアルタイム通信](https://www.amusement-creators.info/articles/advent_calendar/2020/15/ )
116+
- [MirrorとLiteNetLib4Mirrorを使って、UnityでのNetwork Discoveryを行うメモ](https://qiita.com/yanosen_jp/items/4f9b951af68a1c156f74 )
117+
118+
119+
120+
## Mirror KCP: reliable UDP
121+
- https://github.com/vis2k/kcp2k
122+
123+
124+
## P2P.NET
125+
- https://github.com/Phylliida/P2P.NET
126+
- WebRTC
127+
128+
129+
## MidLevel/Ruffles
130+
- https://github.com/MidLevel/Ruffles
131+
- Unity
132+
133+
134+
<br>
135+
136+
137+
# Golang
138+
139+
## go-stun
140+
- https://github.com/ccding/go-stun
141+
142+
143+
## libp2p/go-libp2p
144+
- https://github.com/libp2p/go-libp2p
145+
146+
147+
## Fast RFC 5389 STUN implementation in go
148+
- https://github.com/gortc/stun
149+
150+
151+
## xtaci/kcp-go
152+
- https://devhub.io/repos/xtaci-kcp-go
153+
- https://github.com/xtaci/kcp-go
154+
155+
156+
157+
158+
159+
160+
# Rust
161+
162+
## quilkin - UDP proxy, Rust
163+
- https://news.hada.io/topic?id=4876
164+
- https://github.com/googleforgames/quilkin

udp_network_rudp/resource/00001.PNG

24.1 KB
Loading

udp_network_rudp/resource/00002.PNG

33.3 KB
Loading

udp_network_rudp/resource/00003.PNG

32.4 KB
Loading

udp_network_rudp/resource/00004.PNG

179 KB
Loading
290 KB
Binary file not shown.
Binary file not shown.
35.1 MB
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)