프로그래밍 언어 입문서가 아닌 프로그래밍 기초 개념 입문서
문과생, 비전공자를 위한 프로그래밍 입문책입니다.
jobGuid 꽃미남 프로그래머 "Pope Kim"님의 이론이나 수학에 치우치지 않고 실무에 곧바로 쓸 수 있는 실용적인 셰이더 프로그래밍 입문서 #겁나친절 jobGuid "1판의내용"에 "새로바뀐북미게임업계분위기"와 "비자관련정보", "1판을 기반으로 북미취업에 성공하신 분들의 생생한 경험담"을 담았습니다.
Posted by denoil


안녕하세요. 처음 이렇게 글을 올리게 됩니다.
저는 네오플에 다니고 있는 프로그래머 denoil 입니다.
다들 실력이 쟁쟁하신 분들이라서 제가 이런 글을 올려도 되나 하는 망설여지는데 개발자들끼리 공유하는 것은 좋다고 생각하여 이렇게 글을 올려봅니다.^^

 제가 오늘 발표할 내용은 홀펀칭 입니다. 현재 P2P 게임을 만드시는 분들께서는 모두들 아는 내용이시겠지만 처음 P2P를 접하거나 만드시게 되는 분들께는 도움이 되지 않을까 하여 이렇게 남겨 봅니다. 제가 지금부터 하는 말들은 실전에서 사용 했던 방법을 근거로 이야기 하는 것이지 네트워크 이론을 막 신경써서 하는것이 아님을 미리 말씀드립니다.

 일단 P2P를 사용하는 가장 큰 이유는 역시 빠른 속도 겠지요. 패킷이 서버를 거치지 않고 Peer에게 바로 전송이 되니 그만큼 빠른 것도 없겠지요.
방법에는 TCP를 사용할 수도 있고 UDP를 사용할 수도 있겠습니다. TCP를 사용한다고 P2P가 아닌건 아니지 않습니까? Peer to Peer이기 때문에 서로 직접 연결만 되어 있으면 되는 것 입니다.
허나! TCP를 사용하지 않는 이유는 UDP가 TCP보다 빠르기 때문 입니다. TCP는 패킷을 보장하기 위해 헤더가 더 붙고 뭐 순서를 보장하기 위해 block 하기도 하고 이것 저것 한다고 합니다.(자세한 내용은 책을 참고 하세요) 
UDP는 패킷을 보장하진 않지만 빠르다는 장점이 있습니다. 패킷 손실률이 있어 이부분은 직접 프로그래머가 제어를 해줘야 하는 단점이 있지만 어찌됐든 일반적으로 UDP는 TCP보다 빠르다고 합니다. (중국에서는 UDP보다 TCP가 더 빠르다는 이야기가 있습니다.) 
그래서 최신 P2P게임에서는 UDP를 많이 사용 합니다.

 Peer들 간의 통신을 하기 위해선 서로의 IP, PORT에 패킷을 전송하면 그만 입니다. 그러나 우리는 하나의 고정 IP를 가지고 공유기나 방화벽의 NAT( Network Adresss Translation )라는 장애물을 만나게 됩니다. NAT를 거치게 되면 사설 IP( 192.168.0.2 이런식의 IP )가 지급? 되게 됩니다.


 실제 공인IP 가 아니지요. 사설망에서만 서로간의 통신이 가능한 가상 IP라고 생각 하시면 됩니다. 그래서 NAT단에서 방화벽으로 IP, PORT등이나 인터넷을 막아버리면 아예 인터넷이 불가능 한 그런 상황도 만들어낼 수도 있고 인터넷 연결 없이 사설망에서만 돌아가게 인트라넷을 만들기도 합니다. 사설 IP로 서로 통신을 하게 되면 같은 NAT안에서의 통신은 가능 하지만 서로 다른 NAT에서는 당연히 통신이 되지 않습니다. NAT안에서만 존재하는 가상 IP이기 때문 입니다.
NAT의 종류에도 여러가지가 있습니다.
1. Full Cone NAT
2. Restricted Cone NAT
3. Port Restricted Cone NAT
4. Symmetric NAT
이런것들이 있다고 합니다. 어떤 NAT는 먼저 패킷을 쏴서 포트를 뚫어놔야 하고 어떤 NAT는 먼저 패킷이 와야 포트가 뚤리고 뭐 어떤 NAT는 어쩌구 저쩌구해서 저쩌구 하고 제가 오늘 여기서 설명 드릴 것은 저런 NAT 타입에 대해서는 전혀 모르셔도 됩니다. 왜냐하면 저도 모르니깐요. :D
모로 가도 서울만 가면 된다고 합니다. 이제부터 실전에서 배워보는 홀펀칭에 대해 알아보기로 하겠습니다. 이전 회사에서나 현재 회사에서나 모두 보니 홀펀칭의 방법은 동일 했습니다.

 지금까지 설명드리지 않은 홀펀칭! A4 용지 파일을 정리할때 구멍을 뚫는 펀칭도구를 홀펀칭이라고 부르지요? 말그대로 NAT로 인해 막혀있는 홀( 포트? )를 네트워크 패킷이 지나갈 수 있게 뚫는 것입니다.
방법에는 여러가지가 있습니다. 위에 설명드린 것처럼 누가 먼저 보내고 받고도 있고 포트 번호의 구간을 정해 놓은 후에 하나씩 시도 해보는 방법( 예전 기억엔 그렇습니다. -_- )도 있습니다.
하지만 여기서 포트번호는 한개로 고정 하겠습니다. 포트번호는 임의로 정하되 방화벽으로 막혀 있지 않는 포트 번호를 선택 합니다.
현재 저희 게임에서 사용하고 있는 방법이고 문제 없이 잘 사용 하고 있는 방법 입니다.
그리고 포트 번호 비교를 통해서 현재 어떤 NAT환경인지 체크할 수 있는 내용도 있지만 현재 주제가 길어 질 수 있으므로 생략 합니다. 

간단하게 3단계로 정리 해 보겠습니다.

1. 사설(private) IP로 패킷을 전송해 본다.
2. 안되면 공인(public) IP로 패킷을 전송해 본다.
3. 그래도 안되면 어쩔수 없이 Relay Server로 패킷을 전송해 대신좀 전송해 달라고 한다.

( 여기서 릴레이 서버는 패킷을 중계 해주는 서버입니다. 클라이언트로 부터 받은 패킷을 다른 클라이언트에서 전송만 해주는 역할을 담당하고 다른 일은 하지 않습니다. 지금까지 만난 프로젝트에서는 TCP를 사용했는데 전 회사의 다른 팀 게임에서는 UDP를 사용해서도 했다고 합니다. )

위의 세가지 입니다. 현재 나와있는 넷텐션의 ProudNet 같은 경우 다양한 테스트와 다양한 방법을 사용하여 홀펀칭을 하여 99%의 성공률 보인다고 합니다. ( 끼로님한테 들은 이야기 입니다. -_-)a 문제가 된다면 내용을 삭제 하겠습니다. ) 하지만 여기서 다루는 내용은 홀펀칭을 이용해서 99%의 성공율을 해주지는 못할 것입니다. 릴레이서버의 도움으로 99%까지는 가능 합니다. 기본적인 내용이고 현재 상용게임에서 사용하는 내용임을 거듭 강조 드립니다.

다시 돌아와서 천천히 방식을 전개해 보겠습니다. 위의 3단계를 시행하기 위해선 패킷을 보내려는 상대방의 사설, 공인 릴레이서버의 IP를 알아야 합니다. 그러려면 누군가는 나에게 상대방의 IP 정보를 알려 주어야 겠지요. 그것은 게임 서버가 역할을 하게 됩니다. ( 다른 서버가 해도 되는데 일단 게임 서버라고 하겠습니다. ) 게임 서버에게 나의 IP 정보를 통보하여 서버에서는 정보를 저장하고 있다가 해당 정보를 다른 유저에게 알리는 방식이 되겠습니다.

 이제 서버에게 통보를 할 정보를 수집해 보도록 하겠습니다. 처음 해야 할일은 자신의 IP를 알아내야 합니다. gethostname 함수를 이용하게 되면 자신의 IP를 알 수 있게 됩니다. 그러나 NAT환경에 있게 된다면 현재 나의 IP가 사설 IP 인지 공인 IP 인지 알 수 없게 됩니다. 그러면 공인 IP를 어떻게 알 수 있을까요? NAT환경 밖에 있는 서버는 알 수 있습니다. NAT환경 밖에 있게 되는 서버는 패킷을 받을때 어떤 IP로 왔는지 알 수 있기 때문입니다. 서버와의 통신을 한번 해야 합니다. UDP로 하도록 하지요. TCP로 하면 바인딩하고 커넥션하고 귀찮고 UDP로 간단하게 쏘고 받기만 하면 되는 일이니까요.

자 그러면 공인 IP를 알기 위해서 1바이트짜리의 빈 패킷을 서버로 보냅니다. ( 예를 들어서 빈 패킷일 뿐 제작하시는 분 마음대로 패킷에 내용을 채우셔도 상관 없습니다. )
그리고 서버는 패킷을 받았다면 받은 IP, PORT를 패킷내용에 실어서 패킷을 보내온 클라이언트에게 다시 전송을 해 줍니다. ( 이 과정에서 아마 일단 PORT가 열리는 것으로 알고 있습니다. 자세한 내용은..NAT 관련 문서를 찾아보아야 할 것 같습니다. )

만약 클라이언트가 일정 시간동안 서버로 부터 패킷을 받지 못했다면 다시 시도를 합니다. UDP는 패킷을 보장해주지 않기 때문에 손실이 되었을 수도 있기 때문입니다.
클라이언트는 패킷을 받게 되면 정보수집은 끝 입니다. 
사설IP, 공인IP 모두 알게 되었습니다. 릴레이서버IP는 처음 로그인할때 게임서버에서 받기로 하지요.
이제 수집한 정보를 게임서버에 로그인 한 후에 서버에게 보내주면 준비 끝 입니다.

위의 과정과 앞으로의 과정을 한눈으로 알아볼 수 있게 그림으로 표현 합니다.



내정보 보냈으니 서버에서는 데이터를 가지고 있겠고 각각의 Peer들은 상대방의 IP 정보를 알 수 있게 되었습니다. 사설 IP, 공인 IP, 릴레이서버 IP 모두 알 수 있게 되었습니다. 
이제 파티가 이뤄지기 시작하면 위의 정보를 가지고 처음 위에서 설명 했던 3가지를 시도 합니다.

 

일정 시간 동안 일정한 간격으로 Peer A는  Peer B에게 더미 패킷을 사설 IP로 전송 해 봅니다. 만약 Peer B가 해당 패킷을 받게 되면 상대방에게 받았다고 알려 줍니다. Peer A는  패킷을 받았다면 앞으로 사설 IP로 패킷을 보내면 됩니다.
그러나 일정 시간 동안 받지 못했다면 이번에는 공인 IP로 패킷을 보내 봅니다. 공인 IP로 쐈을때 다시 패킷을 돌려 받았다면 앞으로 공인 IP로 쏘면 됩니다.
일정 시간 동안 또 받지 못했다면 서로 NAT환경에서는 통신이 불가능 합니다. 결국엔 릴레이 서버를 이용해야 하는 상황이 발생하게 됩니다. ( 최대한 릴레이 서버와의 연결은 안붙는게 좋습니다. 한단계를 더 거치기 때문에 느려지기 때문이죠. 그리고 여러명이 붙게 되면 그만큼 릴레이서버에 부담을 주기 때문입니다. )

처음부터 간단하게 다시 정리 해 드리겠습니다.

1. 클라이언트는 gethostname으로 사설 or 공인 IP의 주소를 저장함.
2. NAT환경이 아닌 게임서버 혹은 스턴서버에게 dummy Packet을 보냄. 
3. 서버는 받은 패킷의 IP, PORT로 IP, PORT를 패킷 내용에 담아 클라이언트에게 보냄.
4. 클라이언트는 사설 IP, 공인 IP 모두 저장.
5. 클라이언트는 수집된 사설 IP, 공인 IP를 서버에게 보냄.
6. 파티가 이루어질 경우 서버는 각각의 Peer에게 상대방의 사설,공인 IP를 전송.
7. 각각의 Peer들은 일정시간동안 사설 IP로 패킷 전송.
8. 사설 IP로 패킷 전송 실패시 공인 IP로 패킷 전송.
9. 공인 IP로 패킷 전송 실패시 최후의 보루 릴레이서버에게 맡김.

참 쉽죠잉?

여기서 주의 할점은 서로 패킷통신이 가능해지더라도 일정 시간동안 패킷을 주고 받지 않으면 포트가 막힐 수 있다고 합니다. 그러니 일정 시간동안 패킷이 오가지 않았다면 더미 패킷 혹은 핑 패킷이라도 쏴주면서 포트를 유지 시켜주면 좋겠습니다.

현재 상용게임에서 쓰고 있는 방식입니다. 얼마전 해외 서비스 통계상으로 봤을때 80%이상의 P2P성공율을 보였고 나머지 안되는 NAT 환경은 릴레이 서버를 함께 사용할 경우 98~99%의 P2P성공율을 보이고 있습니다.

많은 P2P 게임을 만드신 분들은 모두들 아는 내용일 것이라고 생각합니다. 각각의 회사마다 방식은 모두 조금씩 다르겠지만 일반적으로 저 방식을 통해서 홀펀칭을 하는 것으로 알고 있습니다. 저는 전문적으로 네트워크를 공부한 입장이 아닌 클라이언트 프로그래머 입니다. 잘못된 내용이 있다면 따끔히 지적해주세요. 저도 소스만 보고 익히고 공부한 내용이라서 틀린 부분도 분명 있을 것입니다. ^^
아무쪼록 여러분들께 좋은 자료가 되었으면 하며 이만 물러 나겠습니다.
긴글 읽어주셔서 감사합니다.

-denoil-

댓글을 달아 주세요

  1. 이전 댓글 더보기
  2. Favicon of http://bluekms21.blog.me 크로스 2012.01.09 18:40  댓글주소  수정/삭제  댓글쓰기

    홀펀칭에 대한 좋은 글 감사드립니다.
    저도 궁금해서 막 인터넷을 뒤져가며 찾아본적이 있었는데
    깔끔하게 잘 정리된 글인것 같아요!
    본문 포함 제 블로그에 퍼가고 싶은데 가능할런지요..?

  3. Favicon of http://bluekms21.blog.me 크로스 2012.01.09 19:02  댓글주소  수정/삭제  댓글쓰기

    http://bluekms21.blog.me/10128882189
    감사합니다. 이렇게 퍼갔습니다. 내용은 전혀 손대지 않았고 앞으로도 좋은 글 부탁드립니다. ^_^

  4. Hybrid 2012.01.09 19:42  댓글주소  수정/삭제  댓글쓰기

    우아~ 홀펀칭 궁금했는데... +_+
    (선리플 후감상)

  5. Favicon of http://rhea.pe.kr/ Rhea君 2012.01.09 22:28  댓글주소  수정/삭제  댓글쓰기

    다음회에 홀펀칭 이야기를 할려고 헀는데 덕분에 포스트가 팍 줄었습니다!!!
    감사합니다. ^^

  6. sgpro 2012.01.10 10:28  댓글주소  수정/삭제  댓글쓰기

    고맙습니다. ^^

  7. Favicon of http://Junios.net Junios 2012.01.10 12:29  댓글주소  수정/삭제  댓글쓰기

    잘 보고 갑니다.

  8. Favicon of https://gamedevforever.com Silverchime 2012.01.10 14:44 신고  댓글주소  수정/삭제  댓글쓰기

    이런게 있군요! 감사합니다

  9. Favicon of https://gamedevforever.com warehouse83 2012.01.10 16:10 신고  댓글주소  수정/삭제  댓글쓰기

    요걸 홀펀칭이라고 하는군요 :)
    한 5-6년전쯤? 네트워킹에 대한 테스트 방책이 별로 없었을때
    공유기 사용하는 유저들이 P2P 방식 사용하는 게임을 하면 안되는 경우가 있어 많이 데었었죠.

    PC방은 보통 IP를 모두 구입해 사용하는데 가정에 공유기 보급이 한참 오르던 시절이라 네트워크에 대한 테스트도 시작했었습니다.

    공유기 메이커에 따라서도 이게 잘되는 놈이 있고 안되는 놈이 있고 그러더라구요 ㅎㅎ

  10. kpro 2012.01.10 18:34  댓글주소  수정/삭제  댓글쓰기

    홀펀칭 내용중에 제일 많이 찾아보게되겠군요. 감사합니다~

  11. 울레리오 2012.01.12 15:19  댓글주소  수정/삭제  댓글쓰기

    안녕하세요 넷텐션 울레리오입니다. 잘보았습니다. 보다보니 저희 프라우드넷 이야기도 나오네요~
    간략하게 저희엔진에 대해 말씀드리면, 저희 엔진은 선 릴레이 후 홀펀칭을 사용하여 reliable한 패킷을 보낼경우 100% 전송을보장합니다. p2p를 하실때 먼저 릴레이 통신이 되게한후 뒷단에서 direct udp가 되도록하면 손실나는 경우를 줄일수 있을거라 생각되네요.

    • 울레리오 2012.01.13 15:18  댓글주소  수정/삭제

      위에보다보니 이런내용이있네요~
      (중국에서는 UDP보다 TCP가 더 빠르다는 이야기가 있습니다.)

      -> 제가 한달정도 중국가서 테스트해본결과 중국도 UDP가 잘됩니다. 홀펀칭율도 약 85% 이상 나옵니다.(다른 동남아 지역과 비슷) 허나 중국인들 인터넷 사용자가 워낙 많아 인터넷사용자가 늘어나는 저녁시간대가 되면 회선망이 과부화되는거 같습니다. TCP도 툭툭끊어집니다. 결론은 트래픽을 줄이는게 관건이라 생각됩니다. 참고하시길 ^^

    • 울레리오 2012.01.13 15:22  댓글주소  수정/삭제

      제 생각에 중국에서 UDP사용을 잘 안하려는 이유는
      보안문제와 천차만별인 중국 인터넷 환경(NAT장비등)을 서버가 부담하는게 좋다고 생각해서 인듯합니다.
      FPS 서비스도 TCP로 하는 게임도 있더군요.
      근데 중국의 인터넷환경이 점점 좋아지는 추세이므로 점점 UDP사용하는 게임들이 늘어나지 않을까 생각됩니다.

    • Favicon of https://gamedevforever.com denoil 2012.01.13 17:24 신고  댓글주소  수정/삭제

      저희 게임도 UDP Module이 시작할때 릴레이서버에 Connection을 먼저 한 후에 한꺼번에 private, public, Realy를 시도하는 루틴이 있습니다. ( 먼저 오는 패킷으로 선택됩니다. )
      그런데 개인적으로 relay Connection수를 줄이고 릴레이서버 부하를 줄이기 위해 위의 방식을 예시로 들었습니다.( private -> public -> realy 시도 순서 )
      홀펀칭 속도를 생각하면 울레리오님이 말씀하신대로 선릴레이 후 홀펀칭을 통해 direct udp를 하는게 맞는 것 같습니다. ^^

    • Favicon of https://gamedevforever.com denoil 2012.01.13 17:26 신고  댓글주소  수정/삭제

      좋은정보 감사합니다. ^^
      중국이 TCP가 더 빠르다는 이야기가 있던것에 대해서는gpgstudy에서 지나가면서 들은 이야기 같습니다. 아마 울레리오님께서 말씀하신것처럼 중국 인터넷환경을 서버가 부담하는게 좋다고 하신 내용 그 내용이었던것으로 기억하는데 잘 기억은 안나네요.
      ( 끼로 말로는 소닉 다니셨다는데 저도 소닉 출신이예요 반갑습니다. ^^ )

    • Favicon of https://gamedevforever.com 끼로 2012.01.13 22:00 신고  댓글주소  수정/삭제

      영운이형이랑 진영이형이 같은 기간에 소닉에 있었는줄 알았는데 아니었네요.. 서로 아는 사이인줄 알았..

  12. 초보자 2012.02.23 22:54  댓글주소  수정/삭제  댓글쓰기

    좋은 글 잘 봤습니다. 질문이 좀 초라하긴 하지만 궁금한 점이 있어서요. 우선 전 프로는 아니고 늦깍이학생입니다ㅎㅎ
    질문은 저기 함수 중에 gethostbyname은 도메인이 있어야 사용할 수 있지 않나요?
    winsock으로 사용할 때는 도메인을 ip주소로 바꾸는 용도로만 사용했었는데, 이 글을 보고
    아무리 찾아도 도메인 넣으라는 글 밖에 없는데, 제가 모르는 사용방법이 있나 해서요. 나중에 시간이 나신다면 조그마한 힌트라도 알려주시면 좋겠어요. 감사합니다.

    • 초보자 2012.02.24 13:15  댓글주소  수정/삭제

      이런 실수를 gethostname를 gethostbyname으로 봤네요. 어떻게 이런 실수를...부끄럽네요. ㅎㅎ 어쨌든 글에 있는 함수를 테스트 했더니 잘 돼요. 감사합니다.

  13. Favicon of http://blog.wimy.com zelon 2012.03.20 01:19  댓글주소  수정/삭제  댓글쓰기

    역시 p2p 상용게임은 비슷한 역할을 해왔었네요. 최후의 수단은 릴레이 서버죠. 저도, 선 p2p 후 릴레이 서버를 썼었었습니다(서버 부하도 괜히 찜찜하고해서;;). 성공률이 100% 인지는 사실 '보장' 을 못해서;; 여튼 99% 까지는 잘 되었던 것 같네요.

    실전에서는 역시 4가지의 NAT 종류보다는, 사설ip, 공인ip, 릴레이서버 정말 이렇게 되는것 같습니다.

    개인적인 의견으로 ^^ 언급하시면 좀 더 좋았을 것 같은게, 같은 NAT 안에서는 공인ip 에 패킷을 보내면 안 간다 정도가 될것 같아요(왜 저렇게 되었는지 과정도 알아두면 좋으니까요~). 공인 ip 라서 아무나 보낼 수 있을 것 같은데 실제로는 내부(!)에서는 공인ip 를 모르더라구요. 즉, "같은 집(같은 공유기 아래)에 있는 컴퓨터들끼리는 사설ip 로만 통신이 된다. 그래서 공인ip 로도 보내보고, (같은 집에 있을 수 있으니) 사설ip 로도 보내본다" 정도를 알고 쓰면 좋을거 같아요~

    실전에서 잠시 쉰지 좀 되어서, 혹시 잘못된거 있으면 알려주세요~

  14. 나그네 2012.04.04 22:34  댓글주소  수정/삭제  댓글쓰기

    포스팅 잘보았습니다..

    세번째방식.. 릴레이서버를 통한 방식은.. 홀펀칭 및 p2p는 아닌것으로 보입니다..
    홀펀칭이 실패했을 때의 대비책 정도???
    그리고 이 방식은 A,B 피어 모두 릴레이 서버에 접속되어 있어야 사용가능합니다.
    B가 릴레이 서버에 접속하지 않은 상태에서는 릴레이 서버 또한 A와 마찬가지로 B에게 패킷을 보낼 수가 없는 것입니다.

    그리고, gethostname으로 얻어지는 ip는.. NIC카드가 여러개 있을 때 실제 연결에 사용된 NIC를 선택하기 쉽지않습니다.
    연결 후에 연결된 소켓에 대해 accept 함수 호출시 받아오는 sockaddr 구조체에 담긴 아이피를 사용하거나, getpeername/getsockname 함수를 통해 sockaddr 구조체를 얻어와 아이피를 확인하여야 할 것입니다.

  15. Favicon of http://ff ffe 2012.06.09 12:09  댓글주소  수정/삭제  댓글쓰기

    제가 잘 몰라서 이해가 안가는점이 있습니다.
    상대방과 서로 다른 NAT환경에 있더라도
    공인 ip로 보내면 통신이 된다는건가요??
    NAT에서 해당 device로 찾아가는 과정이 없어도 자동으로 찾아서 들어가는건가요?? 궁금합니다

    • Favicon of https://gamedevforever.com denoil 2012.06.10 23:29 신고  댓글주소  수정/삭제

      상대방과 서로 다른 NAT에 있더라도 중간에 설명드렸다 시피 중간에 NAT환경이 아닌 서버를 통해서 각각 서로의 클라이언트의 public ip와 port를 얻어오는 부분이 있습니다. 그래서 서로 다른 NAT환경에 있더라도 얻어온 공인 ip,port를 이용해서 보내게 되면 매핑이 되는 것으로 아는데 그걸로도 통신이 안되면 제일 마지막에 설명드렸던 중계 해주는 서버를 통해서 서로 통신을 하는 방법 밖에 없겠지요. 답이 되었는지 모르겠습니다. ^^;;

  16. sownership 2012.06.09 15:59  댓글주소  수정/삭제  댓글쓰기

    쉬운 설명 너무 감사 드립니다 ^^
    큰 도움이 되었습니다.

  17. 죽기살기 2012.06.11 13:13  댓글주소  수정/삭제  댓글쓰기

    안녕하세요. 네트워크를 전혀 모르는 바보 개발자 질문 하나만 할게요~;;
    갑자기 네트워크 관련 프로젝트를 하게 되어 아는게 없어 자료를 찾던중 글쓴이 님의 좋은 포스트를 읽고 궁금한 점이 생겼네요.

    세번째 방식에서 릴레이 서버를 통해 중계를 해야 한다고 말씀하셨는데,
    혹시 클라이언트가 중계서버에게 공인ip(AP의 IP)와 사설IP(AP로부터 얻은 Private IP)를 저장해두어야 하나요? 글을 읽어봐서는 공인IP만 저장을 한다는것 같은데 그렇타면 AP에서는 무엇을보고 사설 IP로 포워딩을 해주는지 이해가 잘 되지 않아서요..ㅠ_ㅠ
    멍청한 질문일지 모르지만 알려주시면 감사하겠습니다~^^;

    • Favicon of https://gamedevforever.com denoil 2012.06.12 11:15 신고  댓글주소  수정/삭제

      아 저 내용에서 릴레이서버의 내용은 완전히 배제 하고 쓴글이라서 자세히 설명하지 않았습니다. 제가 질문의 요지를 잘 파악한것인지 모르겠는데 일단 릴레이서버는 중계 해주는 역할이기 때문에 NAT환경이 아닙니다. 그리고 각각 클라이언트의 public ip, port를 수집하기 위해 게임서버가 중간에서 해준다고 했는데 이 정보를 이용해서 릴레이서버에게 "난 이 ip,port에게 보내고 싶어 네가 대신좀 해줄래?"하고 패킷을 보내면 릴레이서버에서는 패킷을 받으면 패킷 정보를 까서 "이놈한테 보내면 되겠고만" 하고 해당 클라이언트에서 패킷을 던지는 식입니다. 그래서 릴레이 서버를 거치게 되는경우엔 사설 ip,port가 필요없게 됩니다. 그리고 릴레이서버가 어떤 프로젝트에서는 UDP, 어떤 프로젝트에서는 TCP를 사용 한다고 하는데요. TCP로 연결이 맺어진 상태라면 릴레이서버는 패킷을 받아서 연결되어 있는 다른 클라이언트에게 그냥 토스만 하면 됩니다. UDP쪽 홀펀칭은 저 위에 "끼로"님께서 오래전에 했던 부분이라 그분은 여쭤보면 될듯싶습니다.^^

  18. Favicon of http://yoonhs306.tistory.com 죽기살기 2012.06.15 19:32 신고  댓글주소  수정/삭제  댓글쓰기

    안녕하세요. 위에 답변감사합니다~!!
    "끼로"님이 어떠한 분이지 몰라 다시 여기에 질문 하나만 더 할게요..ㅠ_ㅠ

    제가 궁금한 것은 NAT A에 두개의 클라이언트가 물려 있다고 가정하면 어떠한 클라이언트에게
    어떠한 data(infomation)를 보고 어떻게 해당 클라이언트를 찾아 들어가는지 궁금합니다.

    자세히 다시 설명드리면
    지금까지 제가 공부한 바로는..
    1. Client(A)는 서버에게 P2P 통신을 하려는 Client (B)의 Public Ip, Port / Private Ip, Port를 받는다.
    2. 서버로 부터 받아온 Public/Private 주소에 UDP 패킷을 보내고
    if Private 주소에서 받으면 direct로 통신
    if Public 주소에서 받으면, 받은 NAT(B)에서는 받은 패킷의 정보가 없기 때문에 버려진다.
    3. Client (B)에서도 Client(A)로 UDP 패킷을 보낸다.
    4. NAT(A)에는 이미 NAT(B)로 패킷을 보냈던 정보가 저장이 되어 있기 때문에 Client (A)에게 데이터가 전달된다.

    라고 이해를 하고 있습니다. 하지만 이 상황에서 위에 말씀드렸다 싶이 NAT(A)에 두개 이상의 Client가 있다면,
    이 Client들 중에 패킷을 보냇던 Client를 어떻게 구별을 하는지 궁금합니다.
    혹시 시간이 되신다면 답변해주시면 감사하겠습니다.
    그럼 수고하세요..

    • 릴리 2012.06.18 14:49  댓글주소  수정/삭제

      NAT이 뭘까요, 글 초반부에도 있듯이 다른 사설IP를 부여해주는 장치입니다. IP가 다른데 무슨 구별이 필요할까요?

    • Favicon of https://5kyc1ad.tistory.com Mini 5kyc1ad 2017.03.30 17:20 신고  댓글주소  수정/삭제

      (몇년이나 지난 글이지만 혹시 궁금하실 분이 있을까 하여...)

      '죽기살기'님께서 질문하신 내용은 서버 입장에서 한 사설망 내의 두 클라이언트가 접근할 시 공인IP가 같은 클라이언트 두 개를 어떻게 구분하느냐 인것 같은데, 이는 세션을 만들어 패킷 파싱을 통해 구분하는 것이 일반적일 것이라고 생각합니다. 세션이 만들어지기 전이라고 한다면 TCP일 경우는 자동으로 NIC에서 처리해줄 것이니 걱정할 필요가 없고, UDP일 경우에는 IP/PORT를 모두 확인하는 번거로움이 필요하겠지요. (세션을 맺는 중요한 패킷을 UDP로 보내지는 않을 것이라고 생각합니다만...)

      제가 공부한 내용은 사실 서버랑은 큰 관계가 없이 어떻게 공인IP로 들어온 패킷이 한 사설망 내의 다른 사설IP를 가진 여러 클라이언트 중 하나를 찾아가느냐이기 때문에 관점이 정반대이지만 혹시 궁금하실 분이 또 있으실까 하여 공부한 내용을 링크로 달겠습니다.

      http://5kyc1ad.tistory.com/254

  19. 항해자 2012.09.24 10:01  댓글주소  수정/삭제  댓글쓰기

    정보 감사합니다.
    많은 도움이 되었습니다.
    덧글도 읽어보니.. 많은 도움이 되었네요.
    감사합니다.

  20. 퐈니아 2013.07.03 17:18  댓글주소  수정/삭제  댓글쓰기

    잘 보았습니다.
    덕분에 머리속에 밑그림이 그려지는것 같습니다.ㅎㅎ

  21. 지나가다 2013.10.22 16:03  댓글주소  수정/삭제  댓글쓰기

    지나가다가 우연히 봤습니다.
    시간이 꽤 지나서, 댓글 안보실수 있겠지만, 만약 보신다면 답변 좀 부탁합니다.
    다른것은 다 이해가 되는데, "사설 ip로 전송"이라는 것을 이해하지 못하겠네요.
    제가 사설 IP에 대해서 잘못 이해하고 있는 것 같지는 아닌데, "사설 IP로 전송"하는 것이 어떻게 가능하지요? 아니면 제가 모르는 어떤 내용을 생략하십겁니까?

    • Favicon of https://gamedevforever.com denoil 2014.10.01 11:56 신고  댓글주소  수정/삭제

      안녕하세요. 1년이 지난 지금 댓글을 답니다.
      사설 IP는 각각의 Peer들이 서버로 전송해 주고 서버는 accept된 ip,port(공인)와 Peer가 패킷에 전송해준 사설ip,port를 모아 둡니다.
      그리고 Peer들 끼리 연결이 필요할 때 상대방의 사설, 공인 ip, port를 서버에서 전송해 주게 되면 Peer들은 받은 ip, port로 패킷을 쏩니다.
      여기서 사설 IP로 전송은 한번 시도해 보는 것입니다. 같은 NAT환경안에 있는 사람에게는 공인ip,port로는 패킷전송이 안되기 때문에 같은 NAT환경안에 있는 사람이라고 가정하여 먼저 시도해보는 것입니다. 그리고 실패시 공인 ip,port로 전송 하는 것이지요. (순서는 상관없습니다.)