goto문 사용 금지의 실체(1)

by minakim / 2021. 07. 14. [05:12]

 

 

 

 

 
여러 개발자분들과 함께 일하다 보면 가끔 아래의 지침을 마음속에 품고 코딩을 하거나 코드를 리뷰하시는 분들이 있습니다.

"goto문은 절대 쓰면 안된다. 스파게티 코드가 되기 때문이다."

하지만 위의 표현은 정확한 표현이 아닙니다. 저라면 이렇게 표현할 것 같습니다.

"goto를 남용하면 안된다. 스파게티 코드가 되기 때문이다."

 

너무 모호한 표현인가요? 우선 저명한 분들이 남긴 goto에 대한 의견을 살펴보면서 코드를 예로 들어 상세히 설명하겠습니다.

 

 

goto문의 역사

 

최초의 프로그래밍 언어는 기계어에 가까운 언어, 즉 어셈블리어(assembly language)였습니다. 어셈블리어에서는 처음부터 while, if-else, for가 없었습니다. 지금도 없죠. if 조차도 if then goto만 가능하며, if then 뒤에 아무것이나 붙일 수는 없습니다.

제 기억이 틀릴 수도 있지만, 아마도 if 구문이 먼저 나오고 그 후에 if-else, while, for가 나오지 않았을까 추측합니다.

 

 

전산학의 대부였던 다익스트라(Dijkstra)는 이렇게 말했습니다.

 
 
 
 
 
"goto는 해롭다."

 

 

 

이 말에는 이런 속뜻이 있습니다.

 

 

"while, if-else, for는 제외하고 goto만 쓰지 말자."

 

다익스트라가 goto를 절대 쓰지 말라는 의미로 말하지는 않았을 거라고 생각합니다. 이 말은 무려 반세기도 전인 1968년에 한 말이니까요.

 

 

 

 

 

 

 

 

 

 

 

 

1990년대의 유명한 전사학의 대부인 크누스(Knuth)는 이렇게 말했습니다.

 

 

 

 
 
 

"언어 스펙이 발전한 지금은 goto가 나쁘다고만 할 수는 없다"

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2000년대에 리눅스를 만든 장본인인 리누스(Linus)

 

 

"goto가 더 나을 때가 있기도 하다"고 말했습니다.

 

 

 

 

2010년대에 자동차 산업 소프트웨어 안정성 협회 (MISRA)는 "goto 금지는 이제 필수가 아닌 권고로 완화한다"고 명시하기도 했죠.

 

 

2021년인 지금도 우리는 주변에서 종종 "goto는 절대 금지"라는 맹목적인 의견을 내는 사람들이 있습니다.

 

 

이 글을 쓰는 저는 어땠을까요?

 

 

저도 한 때, goto는 절대 금지라는 말을 신봉했습니다.

 

 

 

 

 

 

 

 

 

왜 goto를 쓰지 말라고 했을까?

 

저도 왜 goto를 쓰지 말자는 주의가 팽배했었는지 모릅니다만, 짐작건대 구전되어 내려오면서 서서히 왜곡되었을 것으로 추측합니다. 그도 그럴것이 위의 두 문장인,

 

"goto문은 절대 쓰면 안된다. 스파게티 코드가 되기 때문이다."

 

 

"goto를 남용하면 안된다. 스파게티 코드가 되기 때문이다."

 

중에 그 어느 것도 goto를 어디서 부터 어디까지 쓰지 말아야 하는지를 명확하게 표현해주지 못하기 때문이죠.

 

 

프로그램을 구동하는 것은 기계이지만, 프로그램의 소스코드를 읽고 다루는 일은 사람이 합니다. 즉, 프로그램이라는 한 줌의 텍스트 파일은 우선적으로 사람에게 친화적이어야 합니다.

 

프로그램의 소스 코드가 몇 천줄을 넘어가기 시작하면, 코드를 작성하는데 소요되는 시간보다 기존에 만들어진 코드에 더 코드를 추가하거나 수정하는 데 훨씬 많은 시간이 들어가게 됩니다. 이쯤 되면 코딩하는데 20%의 시간을 쓰고 기존 코드를 읽는데 80%의 시간을 쓰게 됩니다.

 

학교에서 레포트를 제출하거나 단기 연구용 프로그램을 만들 때에는 읽기 쉬운 코드를 굳이 유지할 필요가 없지만, 다수가 참여하는 대규모 팀 프로젝트에서는 타인이 이해하기 쉬운 코드를 만드는 것이 중요해집니다.

 

 

 

 

"내가 누군가의 코드를 잘 이해한다는 것은, 코드를 잘 읽는 내 실력이 뛰어난 것이 아니라 그 코드를 잘 읽을 수 있도록 만든 그 작성자가 탁월한 것이다."

 

goto의 사용 여부는, 바로 이 관점에서 결정되어야 한다는 것이 저의 주장입니다.

 

글로만 설명하면 재미도 없고, 읽기도 힘드니 이 다음 편에서는 바로 코드 레벨의 예시와 함께 소개하도록 하겠습니다.

 

 

 

 

4. 개발 이야기

모바일 게임에서의 실시간 멀티플레이에서 P2P와 CS 네트워킹의 비교

by haley.choi / 2016. 05. 16. [12:18]

모바일 게임에서의 실시간 멀티플레이에서 P2PC/S 네트워킹에 대해 비교하면서 서술 하겠습니다.

 

결론부터 말하자면, 다음과 같습니다.

 

l  Wifi 환경에서 게임을 할때는 높은 확률로 직접 P2P 통신을 합니다.

l  FPS, 레이싱 장르 등 레이턴시가 민감한 게임은 P2P가 효과적입니다.

l  P2P는 해킹에 취약한 면이 있습니다. C/S는 사용법에 따라 해킹에 취약할 수 있습니다.

l  보편적으로 P2PC/S보다 레이턴시(반응 속도)가 더 좋습니다

 

자세한 내용을 말씀 드리겠습니다.
 

 

C/S 네트워킹과 P2P 네트워킹이란

멀티플레이어 게임에서 C/S 네트워킹 혹은 클라이언트-서버 네트워킹을 할 때는, 클라이언트에서의 메시지 가령 플레이어 캐릭터의 이동이나 플레이어가 입력한 명령을 서버에 보내고 서버가 그것을 다른 클라이언트들에게 보냅니다.

             

 

 

P2P 네트워킹 혹은 피어투피어(peer-to-peer) 네트워킹을 할 때는 클라이언트가 직접 다른 클라이언트에게 메시지를 보냅니다.

 

 

 

l  Wifi 환경에서 게임을 할 때 높은 확률로 직접 P2P 통신을 합니다.

 

게임을 할 때 두 기기 사이가 모두 셀룰러 네트워크 즉 3GLTE인 경우에는 홀펀칭 성공률은 제각각입니다.

한국의 경우 통신사마다 다릅니다. KT를 제외하고 나머지 통신사 기기간에는 P2P 홀펀칭이 잘 됩니다.

  SK Telecom LG Telecom KT
SK Telecom O O X
LG Telecom O O X
KT X X X

국내 통신사별 사용자수 통계도 포함해서 P2P 성공율을 산출하면 56%입니다.

한쪽이나 양쪽이 Wifi이면 홀펀칭 성공율은 높습니다.

 

 


 

실시간 멀티플레이 게임에서는 데이터 통신 요금이 발생합니다. 사용자 입장에서는 아무래도 신경이 쓰이죠.

중국에서는 통신 요금이 비싼 중국에서는 메신저앱 푸시 알림이 오면 이를 확인하기 위해 Wifi가 되는 환경을 찾아가기도 합니다

따라서 사용자들은 3G나 LTE 대신 Wifi를 선호하기 마련입니다. 

 


 

 

l   레이턴시가 민감한 게임은 P2P가 효과적입니다.

모바일 네트워크(3G/LTE)의 회선 품질이 좋지 않을 경우에는 P2PC/S의 레이턴시는 큰 차이가 나지 않습니다.

 

하지만 모바일 네트워크(3G/LTE)의 품질이 좋을 때는 P2P C/S 간의 차이가 확연해집니다.

 

품질이 좋은 모바일 네트워크(3G/LTE))에서는

P2P의 경우 약 2ms,

C/S에서는 약 12ms

처리 딜레이를 확인할 수 있습니다. (환경에 따라 다소 차이가 있을 수 있습니다.)

 

아마도 FPS 게임을 주로 하는 유저들은 레이턴시 10ms의 차이가 무엇을 의미하는지 절실하게 공감할 것입니다



 

 

 

 

l   P2P는 해킹에 취약한 면이 있습니다. C/S는 사용법에 따라 해킹에 취약해질 수 있습니다.

 

C/S 방식인 실시간 멀티플레이 온라인 게임의 경우 멀티플레이 동기화를 하는 방식은 크게 세가지로 구분됩니다..

  

l  방식 1: 클라이언트에서 명령을 보내는 방식 (Player 1 -> Player 1 Input(Scene Update))

l  방식 2: 클라이언트에서 연산된 플레이어 이동 정보만을 보내는 방식

 

방식1은 방식2에 비해 클라이언트 해킹에 강합니다.

그 이유는 플레이어 캐릭터에 대한 이동 연산을 서버에서도 처리하기 때문입니다.

하지만 scene update를 서버에서 모두 처리하는 것은 서버 성능에 있어서 상당한 부하를 차지합니다.

 

더 큰 문제가 발생하는데, 방식2보다 게임 플레이 중에 발생하는 끊김 현상 혹은 랙 현상이 더 심합니다.

 

<방식1을 쓴 게임의 랙 현상 https://www.youtube.com/watch?v=83i8Yzkkzvg>

 

방식2는 방식1과 달리, 플레이어 캐릭터에 대한 이동 연산을 클라이언트가 합니다. 따라서 방식1과 달리 해킹에 약합니다. P2P는 해킹에 약하지만 방식 1도 P2P와 거의 동급으로 해킹에 약합니다. 그나마 할 수 있는 최선은, 클라이언트의 연산이 해킹된 결과인지를 검사하는 것 뿐입니다.

방식1의 장점은 방식1보다 훨씬 쾌적한 멀티플레이입니다. 레이턴시에 덜 민감하기 때문입니다.  

 

모바일 게임은 무선 네트워크(WIFI/3G/LTE)를 사용합니다.

문제는 무선 네트워크의 레이턴시가 유선 네트워크에 비해서 편차가 크다는 데 있습니다.

무선 네트워크의 품질이 양호하더라도 간헐적인 큰 레이턴시는 피할 수 없습니다.

방식2는 간헐적인 큰 레이턴시가 일어나더라도 대부분 게임 플레이중에 이상함을 못 느낍니다.

하지만 방식1은 큰 레이턴시가 일어날 때 마다 게임플레이가 stuttering이 일어납니다. 화면이 잠깐 잠깐씩 멈춰버리는 현상입니다.

 

이러한 문제점 때문에 대부분의 모바일 게임에서는 클라이언트-서버 네트워킹을 할 경우 어쩔 수 없이 방식2를 사용하고 있습니다.

 

모바일 P2P 네트워킹에서는 플레이어의 이동 처리를 클라이언트가 담당합니다. 따라서 해킹에 취약할 수 밖에 없습니다.

그러나 클라이언트-서버 네트워킹으로 만든다 하더라도 방식2를 선택하는 이상 P2P 네트워킹과 마찬가지로 해킹에 취약해집니다. 해결하려면 방식1을 써야 하지만 게임의 질을 크게 떨어뜨리므로 선호되지 않고 있습니다.

 

 

l   보편적으로 P2PC/S보다 레이턴시(반응 속도)가 좋습니다.

 

멀티플레이에서 P2P 네트워킹을 적용하는 방식은 크게 두가지가 있습니다.

l  수퍼피어 방식: 클라이언트 중 하나가 모든 플레이어의 scene update를 담당합니다. 흔히들 리슨 서버 방식이라고 말합니다.

l  대칭피어 방식: 각 클라이언트가 각자 플레이어의 scene update를 담당합니다. 리슨 서버 방식이 아닙니다.

 

 

   

수퍼피어 방식은 패키지 게임에서 시작된 방식이며 이 방식은 일부 온라인 게임에서도 사용되고 있습니다. 서버에서 처리하기에는 scene update 들의 연산량이 많거나, 대칭피어 방식으로 개발하기 힘든 이유가 있을 때에 쓰이기도 합니다.

 

불가피한 경우가 아닌 이상 수퍼피어 방식을 피해야 합니다.

수퍼피어 방식의 경우 슈퍼 피어로 선정된 플레이어가 게임 플레이 도중 이탈할 때 함께 플레이하던 다른 플레이어들도 게임이 중단된다는 문제점이 있고, 수퍼 피어의 처리 성능이 나쁠 경우 다른 플레이어들도 모두 악영향을 받습니다.

 

따라서 많은 온라인 게임에서 P2P 네트워킹은 대칭피어 방식으로 사용됩니다.

대칭피어 방식에서는 각 플레이어의 위치 정보를 직접 다른 클라이언트들에게 전송합니다.

그러므로 플레이어는 C/S 방식으로 플레이할 때보다 빠른 반응 속도를 느낄 수 있습니다.

설령 P2P 홀펀칭을 못해서 릴레이를 하게 되고 이로 인해 느려졌다고 하더라도 C/S 방식으로 통신하는 게임과 동일한 레이턴시를 확인할 수 있습니다.

 

P2P방식은 C/S방식보다 더 빠른 반응 속도를 제공하며, 최악의 경우에도 반응 속도는 C/S 방식과 똑같아집니다.

 

 

P2P 네트워킹의 여러 가지 용도

P2P 네트워킹은 더 빠른 반응 속도의 멀티플레이뿐만 아니라 다음 용도로도 활용됩니다.

 

l  클라이언트간 많은 양의 트래픽이 발생하는 경우 (예시: 음성, 화상 대화 등)

l  서버에서 처리하기에는 너무 많은 양의 연산을 해야 하는 경우 (예시: 게임 물리 엔진 연산 등)

 

이에 대한 자세한 내용은 프라우드넷 도움말 P2P 통신에 대한 (한국어)에서도 설명하고 있습니다.

 

 

 

 

 

 

4. 개발 이야기

기기간 시간 동기화 방법

by Sophia Lee / 2016. 04. 29. [07:58]

게임을 개발하다 보면, "두 기기 간의 시간 동기화를 하는 방법"이 필요할 때가 있습니다.

이것에 대해서 알아 봅시다.

 

두 기기의 시간을 동기화하는 것은 일반적으로 round trip latency (RTT)를 이용하는 방법입니다.

 

기기 A,B가 있다고 있다고 칩시다.

 

* A->B: A의 시스템 시간을 보낸다.[1]

* B->A: [1]을 그대로 보낸다.

 

A에서는 A의 시스템 시간에서 [1] 안의 시간을 빼면 RTT를 얻게 됩니다.

이제,

 

* A->B: RTT[2]와 A의 현재 시간[3]을 보낸다.

 

이렇게 하면 됩니다. B에서 A의 현재 시간을 얻고 싶으면,

 

* A의 현재 시간 = [3] + [2]/2

 

를 계산하면 됩니다.

 

NTP도 이와 비슷한 방식으로 작동합니다.

컴퓨터 네트워크의 특징상 RTT는 한번만 측정한다고 정확하다고 말할 수 없습니다. 매번 RTT는 조금씩 틀리기 때문입니다. 무선 네트워크에서는 크게 틀리는 경우도 있습니다.

따라서 여러번 잰 후 최근 것의 평균을 내는 것이 더 정확합니다.

 

참고로, 프라우드넷(proudnet.com)에서 다양한 시간 동기화 함수를 제공합니다. 

 

* CNetClient.GetIndirectServerTimeMs

* CNetClient.GetP2PServerTimeMs

* CNetClient.GetServerTimeMs

 

프라우드넷은 서버 뿐만 아니라 P2P 연결된 다른 클라이언트와의 RTT를 얻는 기능도 제공합니다.

CNetClient와 CNetServer의 GetLastPing와 GetRecentPing 함수를 이용해서 말이죠.

4. 개발 이야기

애플의 IPv6 관련 리젝트 정책에 대한 해결 방법

by Sophia Lee / 2016. 01. 19. [04:44]

안녕하세요, 넷텐션입니다.

오랜만에 개발 이야기로 인사 드립니다. (_ _)

신년부터 애플의 IPv6 관련 리젝트 정책으로 개발 업계가 술렁이는데요,

넷텐션에서 리젝트 안 당하는 법을 알려 드립니다!

 

1. 네트워킹 프레임 워크를 사용할 것

2. IPv4 전용 API를 쓰지 말 것

3. 하드코딩 주소를 쓰지 말 것

3 steps to make an app work with IPv6

출처: 링크 
 
각 설명을 해 드리자면,
 
----------------
 
1. 네트워킹 프레임워크를 사용할 것 
 
iOS SDK 자체에 있는, 소켓 윗단에 구현되어 있는 네트웍 프레임워크라던지, 혹은 제3의 네트워크 프레임워크를 쓰는 것을 권장한다는 뜻입니다. 네트웍 프레임웍을 쓰신다면 위 2는 웬만하면 고려 안하셔도 될 것입니다. 만약 써드파티 네트웍 프레임웍을 쓰시고 있으시면, 해당 프레임웍 개발자에게 이 질문을 꼭 하셔야 하겠습니다. "IPv6 지원하나요?"
 
네트웍 프레임웍의 일종인 프라우드넷은 IPv6에 대응되어 있습니다. 2015년 12월 업그레이드 릴리즈에서 대응했습니다. 프라우드넷을 쓰시는 분은 IPv6 지원을 원하시면 2015년 12월 업그레이드 혹은 이후 릴리즈를 적용하셔야 합니다. 
 
----------------
 
2. IPv4 전용 API를 쓰지 말 것
 
직접 소켓 프로그래밍을 하신다면, IPv4 전용 API를 쓰시면 안됩니다. 가령 이런 함수들을 쓰시면 안됩니다. (이런 함수들을 쓰는 것 자체가 애플에서 리젝되는지는 확인되지는 않았습니다만, 아무튼 프라우드넷에서는 이들 함수들을 전혀 쓰지 않습니다.)
 
inet_addr()
inet_aton()
inet_lnaof()
inet_makeaddr()
inet_netof()
inet_network()
inet_ntoa()
inet_ntoa_r()
bindresvport()
getipv4sourcefilter()
setipv4sourcefilter()
 
IPv6에서 잘 작동하는지 테스트하려면, IPv6 주소만 있는 네트워크 환경을 만들어야 합니다. 여러가지 방법이 있는데요, 저희의 경우 맥 기기를 이용해서 만들었습니다. 
 
----------------
 
3. 하드코딩 주소를 쓰지 말 것 
 
애플에서는 '하드코드 주소'라고 표현했는데요, 이는 대중들에게 쉽게 의미를 전달하려고 일부러 저렇게 표현한 것 같습니다. 
정확한 명칭은 IP literal입니다. 가령, "11.22.33.44"입니다.
 
한편 우리가 흔히 말하는 '호스트 네임' 가령 "server1.mygame.com" 같은 것은 FQDN(fully qualified domain name)이라고 부릅니다.
 
만약 하드코드 주소 즉 IP literal을 직접 이용해서 서버에 접속하면 어떻게 되냐고요? 일부 IPv6 네트워크의 클라이언트가 IPv4 네트워크의 서버에 접속을 못하는 경우가 발생할 수 있습니다. (iOS 9.2 이후부터는 이 문제가 일부 해결되긴 합니다만 이 또한 모든 IPv6 네트워크에서 된다는 보장도 없습니다.)
 
이 반대도 마찬가지입니다. 클라이언트는 IPv4인데 서버가 IPv6인 경우요.
 
접속을 왜 못하는지는, NAT64/DNS64의 작동 얼개로 설명됩니다. 내용이 길기 때문에 일단 논외 하겠습니다.
 
그럼 어떻게 해야 하느냐? 애플이 지령(?)한대로 따라야 합니다. 서버는 IPv4 literal 대신 FQDN으로 접근 가능해야 합니다. 클라이언트는 서버에 접속할 때 FQDN을 써야 하고요.
 
위 내용을 예로 들어 설명하자면, 
 
- 11.22.33.44 ==> 애플에서 밴 먹임
- server.mygame.com ==> Ok
- 11:22:33:44:55:66:77:88 ==> 애플에서 밴 먹임
 
 
 
서버 세팅을 하시는 분들은, 각 서버에 대한 DNS 세팅을 모두 해주어서 각 서버가 FQDN을 가지게 해주어야 하죠. 그리고 클라이언트는 각 서버에의 접속을 할 때 IP literal이 아니라 FQDN으로 서버에 접속을 해야 하겠죠.
 
만약 각 서버에 대해 지금 당장 FQDN을 배정하기 힘들 때를 위해, 프라우드넷에는 응급처치 방법을 제공합니다.
 
프라우드넷 기반 서버에 접속하는 IP literal을 입력하되, IPv4에 물려있는 다른 서버 X의 FQDN도 추가로 입력하면 됩니다. X는 실제로 접속은 안하니 걱정 마시고요, 그저 DNS 검색 대상만 될 뿐입니다. 이것이 있으면, 100% 보장하지는 않습니다만, [1] IPv4 literal만 갖고도 서버에 접속을 할 수 있습니다. 
 
CNetClient* nc = CNetClient::Create();
p.m_serverIP = "11.22.33.44";
p.m_publicDomainName1 = "www.nettention.com";
p.m_publicDomainName2 = "www.nts.go.kr"; // 네 그렇습니다. 국세청입니다. -_-;;;
nc->Connect(p);
 
(C#도 가능하나 일단 생략)
 
어떻게 IPv4 literal만 갖고 접속을 할 수 있냐면... NAT64의 '주소조합 알고리즘'을 구현했기 때문입니다. 이 또한 내용이 기므로 일단은 생략 ^^
 
아무튼 위 API를 쓰는 것은 어디까지나 응급처치 방법입니다. 완전한 해결을 하려면 애플의 지시(?) 사항 "FQDN으로 서버에 접속해라"를 따라 주어야 합니다.
 
---------------------
 
논외: IPv6 주소가 쫙 퍼지면 인터넷 공유기는 사라지지 않을까?
 
IPv6 주소가 쫙 퍼지면 인터넷 공유기는 "이론상으로" 사라져도 됩니다. 인터넷 공유기 자체가 모자란 인터넷 주소 갯수를 해결하기 위한 방법 중 하나니까요. 
 
그러나, IP 주소당 가격을 매기는 인터넷 상품을 파는 업체가 IPv6라 하더라도 IP 주소를호락호락 추가 비용 없이 뿌리지는 않을 것입니다. 그렇다면 얄짤없이 인터넷 공유기를 갖다 붙이는 노력을 안할래야 안할 수 없죠. 인터넷 공유기에 강한 프라우드넷도 IPv6 세상에서 여전히 존재 필요성이 있을 것입니다.
 
-----------------------
 
즐코딩 하세요~
 
-------------------
 
[1]: 맥 기기를 포함해서 일부 클라이언트 사이드 IPv6 인터넷 공유기에서는 정상 작동합니다.

4. 개발 이야기

ProudNet의 UDP 혼잡 제어 기능

by Sophia Lee / 2015. 08. 20. [06:08]

프라우드넷을 쓴 게임 중 하나가 2011년에 중국에서 문제를 일으켰다는 사건이 화제가 되었던 적이 있습니다. (관련 링크문제의 현상은 P2P나 C/S간 UDP 통신량이 지나치게 많을 때 클라이언트-서버간 TCP 연결이 중간에 끊어져 버리는 것이었습니다. 이 문제의 근본 원인은 과도한 UDP 사용량이 불러일으킨 인터넷 블랙아웃 현상이었습니다. 이것을 해결하려면 UDP 통신량이 블랙아웃을 일으키지 않을 만큼 사용량을 낮추어야 합니다. 당시에는 그 문제를 해결하기 위한 많은 노력을 했고, 이를 해결하는 기술이 지금의 프라우드넷으로 이어지고 있습니다.

여기 두 단말기가 있습니다. 클라이언트-서버 관계일 수도 있고 클라이언트-클라이언트 즉 P2P 관계일 수도 있습니다. 두 단말기 간에는 UDP 통신과 TCP 통신이 같이 사용되고 있습니다.

 

 

 

두 단말기간 데이터 통신량을 증가시키겠습니다. 그러면 두 단말기 간에 있는 네트워크 장치(라우터나 방화벽 등)에는 처리량이 증가하기 시작합니다. 이때 일부 네트워크 장치들은 특정량 이상의 데이터 통신을 모두 처리하지 않고 슬슬 버리기 시작합니다. TCP는 스스로 이를 감지합니다. 그래서 송신 단말기의 내부에서는 보낼 데이터가 블러킹이 일어나는 대신 통신량이 증가하지 않습니다. (정확히 말하자면 한계선 즈음에서 오르락 내리락 합니다.) 

그러나 UDP는 그러한 감지를 할 수 없습니다. 따라서 데이터는 블러킹이 안 일어나지만 통신량이 끝없이 증가합니다. 그리고 두 단말기 간의 네트워크 장치는 지나치게 쏟아지는 UDP 패킷을 처리하지 못하고 버리기 시작하는데 이때 TCP를 위한 패킷도 덩달아 버려집니다. 이것이 Windows OS 기준으로 20초 이상 계속되면 TCP 연결이 끊어집니다.

 

중국의 인터넷 환경은 한국과 달리 네트워크 장치의 처리량 한계에 쉽게 부딪힙니다.

TCP는 네트워크 장치에서 패킷을 버리는 것을 감지하면 스스로 통신량을 줄인다고 했습니다. 이를 혼잡제어(congestion control)이라고 말합니다. 그렇다면 이 문제를 해결하기 위해서는 UDP 신 또한 혼잡 제어 기능이 있으면 되겠죠. 하지만 TCP의 혼잡제어 기능은 ARQ 알고리즘에 근거하여 만들어져 있는데 이를 UDP에 그대로 적용하기에는 무리가 따릅니다. 반대 방향으로의 트래픽량이 많이 증가하는 등의 문제가 있습니다.

프라우드넷에 사용되는 UDP 용 혼잡제어 기능을 소개하겠습니다. 이는 다음과 같이 작동합니다.

1. 송신자 측에서는 일단 마음껏 데이터를 보냅니다.

2. 수신자 측에서는 받은 데이터의 패킷 유실율과 데이터 수신 속도를 측정합니다. 이를 일정 시간마다 송신자에게 회신합니다. 

3. 송신자 측에서는 회신된 데이터를 근거로 데이터 송신 속도를 제한합니다. 만약 패킷 유실이 전혀 없으면 제한 없이 보냅니다. 만약 패킷 유실율이 높아지면 송신자가 회신 준 실제 데이터 수신 속도를 감안해서 송신 속도를 제한합니다.

 

 

프라우드넷의 UDP 혼잡제어를 간단히 소개해 드렸습니다. 상기 기술은 넷텐션의 국내외 등록 특허(2014년 출원, 2015년 등록됨)입니다. 

한편, 프라우드넷의 P2P 통신에서는 UDP로 일반 메시지를 주고 받는 기능 말고도, reliable UDP 계층을 통해 TCP처럼 신뢰성 통신을 할 수 있는 기능도 따로 있습니다. 여기에는 위의 기법이 아닌, TCP와 비슷한 방법으로 혼잡 제어를 하고 있습니다.

프라우드넷의 UDP 혼잡제어 기능은 꽤 많이 검증되었지만, 아직까지도 전세계 모든 네트워크에서의 검증이 완벽하다고 자신하지는 않습니다. 더 나아지는 모습을, 앞으로도 많이 지켜봐 주세요.

4. 개발 이야기

Perforce의 Backout 기능

by Sophia Lee / 2015. 07. 03. [10:22]

넷텐션에서는 개발 프로젝트에서 소스 파일 관리를 위해 Perforce Helix를 사용하고 있습니다. Perforce는 유상 구매해야 하는 소스 컨트롤 소프트웨어입니다. 유상이니만큼 가격의 부담이 있지만 그만큼 제값을 합니다. GitHub처럼 부수적인 파일로 인해 폴더 크기가 비대해지지 않고, 파일 처리 속도도 빠릅니다.

Perforce에는 알게 모르게 깨알 같은 기능이 있는데요, 그 중에 하나가 Backout 기능입니다. Backout은 이미 submit 혹은 check in 한 것을 취소하는 기능인데요, 이미 submit 한 내역을 지우는 방식이 아니라, submit 하기 전의 상태로 다시 한번 submit을 하는 데 사용됩니다.

그런데 이 Backout 기능에는 흥미롭고 멋진 기능이 있는데요, 바로 submit을 한 이후의 다른 submit을 했던 것을 날려먹지 않으면서 특정 submit을 롤백시켜 버리는 기능입니다.

한 예를 들어 보겠습니다. 다음과 같은 함수가 있습니다.

  

 그런데 이 함수에 버그가 있습니다. 그래서 원인을 추적하기 위해 로그를 출력하는 루틴을 추가했습니다.

 

 그런데 이것을 오랫동안 submit을 안 하고 작업하니까 불안합니다. 백업을 하고 싶습니다. 그런데 기왕이면 Perforcesubmit하는 형태로 백업을 하고 싶습니다. 그래서 쿨하게(!) submit을 했습니다.

 

 코드를 아래와 같이 수정했습니다. 그리고 submit 했습니다.

 

 

 

, 드디어 버그를 찾았습니다! 문제의 라인을 삭제했습니다. 그리고 submit 했습니다.

 

 그런데, 앞서 submit한 것 즉 change 25683의 임시로 넣은 코드가 있습니다. 저것은 지우고 싶네요. Change 25683의 변화 내역(diff)를 열어서 하나 하나 수정하는 방법도 있지만, 이러한 경우 PerforceBackout으로 한큐에 해결할 수 있습니다.

Change 25683에 우클릭 후 Backout을 선택하면 뭔가가 수정된 채 check out 됩니다. Backout 실행 후 get latest version과 Resolve를 해주는 것 잊지 마시고요.

 

 Backout을 실행 후 만들어진 check out 된 파일에 대해 변화 내역(diff)를 열어보면, 놀랍게도 로그 코드를 추가한 이후의 수정사항 들이 모두 유지된 채로, 딱 로그 코드만 뿅 사라져 있습니다!

 

 자 이제 submit 고고고. 소스를 직접 수정하지 않고도 로그 코드가 사라졌습니다.

  

 Perforce는 이밖에도 많은 수의 브랜치(stream)을 관리하는데도 편리하고, 과거 파일을 빨리 얻는다던지, 오래된 파일이나 다른 폴더와의 통째 비교를 빠르게 보여주는 등 여러모로 편리합니다.

 돈을 주고 시간을 살 수 있는 방법이 있는데요, 좋은 개발 소프트웨어를 도입하는 것이 그 방법 중 하나죠. 프라우드넷도 서버 개발에 대해서 시간을 돈 주고 사는 좋은 방법이기도 하죠.

4. 개발 이야기

프라우드넷 유니티 튜토리얼 동영상 업데이트!

by nettadmin / 2013. 11. 11. [11:16]

 

프라우드넷 유니티 튜토리얼 동영상의 목소리 멘트를 한글, 영어 자막으로 바꾸었습니다!

스피커 안되셨던 분들은 재 도전(?)해보세요~!

http://www.nettention.com/introduction/tutorial/unity3d

4. 개발 이야기

Unity 3D를 이용한 프라우드넷 사용법 동영상

by nettadmin / 2013. 07. 25. [09:10]

Unity 3D를 이용한 프라우드넷 사용법 동영상이 youtube에 올라왔습니다.

 

http://www.youtube.com/results?search_query=nettention+ProudNet+social+game+programing

4. 개발 이야기

프라우드넷과 유니티엔진을 이용해서 소셜 게임 만들기 동영상

by nettimays / 2013. 04. 17. [11:47]

프라우드넷과 유니티엔진을 이용해서 아주 기본적인 소셜 게임 만드는 과정을 보여주는 동영상입니다.

(링크)

주요 소개 내용은 다음과 같습니다.

  • 프라우드넷과 유니티엔진을 같이 사용하기
  • 프라우드넷의 네트워킹 시스템 사용하기
  • 프라우드넷의 DB cache 시스템 사용하기

 

4. 개발 이야기

게임서버에 대해 말해주마 - 5부, 해킹 기술의 작동과 방어 원리

by nettadmin / 2012. 05. 17. [06:54]

inven에 연재 중인 배현직 대표의 '게임서버에 대해 말해주마' 5부가 나왔다. 

이번에는 '해커와 개발자의 두뇌 싸움', 해킹 기술과 방어 원리에 대해 라는 주제로

게임 개발자들이 해킹 방어를 위해 어떤 노력을 하는지에 대해 소개하고 있다.

 

기사원문

4. 개발 이야기