TCP 홀펀칭... 아직도 bind error 해결을 못하고 있습니다...ㅠㅠ
안녕하세요 (_ _) 거의 2주전부터 이곳 좋으신 분들의 도움을 받아 열심히 여쭤보고 답변 받아가며 개발을 하고 있습니다..
근데 아직도 bind error 부분 해결을 못했네요 ..ㅠㅠ
그래서 이번엔 스샷까지 첨부합니다;;;
첫 그림이 TCP 홀펀칭이 이루어지기 위한 클라이언트 구조 그림인데요..... 그림과 같이 클라이언트는 자신의 로컬포트를 이용하여
서버와 연결을 해야하고 , 또 상대방 클라이언트의 연결 요청을 Listen 하고 있어야 하며, 상대방 클라이언트에게 connect 시도를 해야합니다..
즉 하나의 같은 로컬포트에 소켓이 3개가 bind 가 되어야 하는거지요...(같은 포트를 이용해야 하는 이유는 NAT의 맵핑테이블을 이용해야하기 때문입니다)
두번째 그림은 서버와 서버연결에 사용될 소켓과 포트번호, 로컬포트 번호 등 소켓 및 포트 정의 부분이구요
세번째 그림은 클라이언트가 서버와 연결하기 위한 소켓 초기화 및 바인드 부분.
네번째 그림은 상대방 클라이언트의 연결요청을 감시하기위한 Listen 소켓 초기화 및 바인드 부분. (클라이언트가 서버와 연결된 소켓은 close 함)
다섯번째 그림은 상대방의 사설 및 공인IP 로 connect 요청을 하기 위한 소켓초기화 및 바인드 부분입니다.
이렇게 프로그램을 구성 후 돌리게 되면 네번째 그림의 bind함수 부분에서 마지막 첨부그림과 같이 bind 에러가 납니다...ㅠㅠ
이런 에러를 방지하고자 같은 포트에 여러소켓 바인딩이 허용되도록 setReuseAddress 를 써준걸로 알고 있는데 말이죠;;;
혹시 구글링하다보니 BSD 시스템들은 SO_REUSEPORT 옵션도 켜주어야 한다고 하는데... 이게 해결책인가요??
근데 아무리 봐도 JAVA 에서는 SO_REUSEPORT 비슷한 메소드가 보이질 않네요...;;
제발 도움 좀 부탁드립니다...ㅠㅠ
너무 답답해서 해결만 된다면 진짜로 사례라도 해드리고 싶은 심정입니다...
그럼 다들 좋은하루보내시고 날씨 쌀쌀한데 감기조심하세요!! (_ _)
첨부 | 파일 크기 |
---|---|
TCP 홀펀칭 구조.PNG | 99.65 KB |
소켓 정의.PNG | 8.96 KB |
서버와 연결 소켓.PNG | 10.62 KB |
p2p 리슨소켓.PNG | 10.94 KB |
p2p 커넥션소켓.PNG | 9.83 KB |
_화면.JPG | 73.79 KB |
음 ..
하나의 ip:port 에 여러개의 socket 이 bind 할 수 없습니다.
NIC 가 여러개라면 각각의 NIC 에 같은 port 번호로 bind 할 수는 있지만..
INADDR_ANY 로 먼저 bind 한 놈이 있다면 그것도 안 될거구요.
listen 하고 있던 socket 이 close 되면, 기존에 연결되어 있던 세션이 close 되면서 TIME_WAIT 상태로 빠지는데..
이 때에는 세션이 모두 CLOSE 되기 전까지는 같은 port 에 bind 가 안 됩니다.
그 상태에서 다시 프로그램을 실행해서 bind 를 하고자 할 때 쓰는게 SO_REUSEADDR 옵션입니다.
여러 socket 이 동일한 ip:port 에 bind 할 수 있는 방법은 없습니다.
TCP 는 bind -> listen 한 상태에서, 새로운 socket 으로 bind -> connect 가 안되고..
또 listen 한 socket 으로 connect 할 수 없는데..
UDP 는 bind -> listen 한 socket 으로 send, recv 가능합니다.
TCP 라면 명시적으로 서버-클라이언트 같이 계층 구조를 두고 누가 connect 를 해야 할지 결정해야 할 것 같은데요..
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
음 ..
전에 올리셨던 글들 대충 살펴봤는데..
UDP 를 쓰더라도 신뢰성 있게 데이터를 송수신할 수 있는 방법은 있습니다.
Datagram 에 TCP 와 비슷한 헤더를 붙여서 직접 송수신확인을 하는거죠.
Reliable UDP 로 검색해 보세요.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
NAT traversal 관련하여 이전에 본 기억으로는...
C 언어 RAW socket API 로 administrator 권한에서 하는 걸 본 기억이 나네요
자바에서 가능한지 모르겠습니다.
그니깐 outbound socket(client socket)의 source port 를 정할때
RAW socket API 를 사용해야 하고 이때 privileged 권한이 필요합니다.
댓글 달기