소켓 프로그램에서 송수신으로 가장 많이 사용되는 것은 recv,send 와 recvfrom, sendto 일 것이다. 전자를 TCP 용 후자를 UDP 용으로 흔히 알고 사용하는데, 그 이유는 연결지향형이 아닌 경우 매 패킷마다 주소지가 다른 데이터가 올라 올 수 있기 때문에 주소를 받거나 보낼 수 있는 시스템 콜을 사용하게 된다.

UDP의 경우 기대되는 데이터의 흐름은 다음과 같다.

서버

1. UDP 서버가 대기
2. 패킷 및 클라이언트 주소 수신
3. 클라이언트 주소로 응답 송신

클라이언트
1. 서버주소 및 요구사항 송신
2. 패킷 및 서버 주소 수신

여기서 주의할 점이 클라이언트가 데이터를 송신하고서 recvfrom 으로 대기하고 있다면, 서버가 아닌 다른 누군가가 패킷을 쏜다면 (이것은 네트웍 중간에 있는 녀석이 충분히 만들어낼 수 있다.) 그것을 자료인 양 수신하게 된다. 이 경우 클라이언트쪽에서 받은 응답만 보는 것이 아니라 udp 주소를 보고 과연 내가 보낸 송신자로부터 왔는지 확인한 후 잘못된 곳에서 왔다면 다시 대기하여야한다. UDP 포트에 아무데이터나 쏘고 없을때 돌아오는 ICMP 를 확인하는 수준의 포트스캐너가 순간 다녀간다면, 오동작할 것이 뻔하다. 환장한다.

이런 경우를 대비해서 UDP 클라이언트는 connect, send, recv를 사용하여 프로그램하는 것이 올바른 방법이다. 책을 보면, udp 소켓에서의 connect는 실제 접속을 시도하는 것이 아니라 이후에 올 send에 대해서 전송할 주소를 설정해 두는 것이고, recv에 대해서 그 주소외에서 오는 응답은 필터링을 하는 역할을 한다. 그렇다면, 당연히 UDP 클라이언트 프로그램은 connect를 사용해야하는 것이 정답이다. 예외가 없다.

정리하자면, UDP 프로그램의 서버는 sendto, recvfrom 조합을 클라이언트는 connect, recv, send를 쓰는 것이 일반적이라는 것이다.

신고
  1. kukuta 2007.03.16 20:45 신고

    "udp 소켓에서의 connect는 실제 접속을 시도하는 것이 아니라 이후에 올 send에 대해서 전송할 주소를 설정해 두는 것이고, recv에 대해서 그 주소외에서 오는 응답은 필터링을 하는 역할을 한다."

    라는 것에서 만일 서버의 아이피가 여러개일 경우에는 connect로 설정되는 주소가 어떻게 되는건가요?
    저런식으로 하면 서버의 아이피모두를 골라 줄수 있는것인가요??

    kukuta@gmail.com

    • 최호진 2007.03.16 23:17 신고

      connect 대상은 packet을 전송할 주소만 저장하는 것이고, 실제 multi-homed nic의 경우 여러 IP 중 하나가 선택되는 것은 어떻게 bind 했는지에 따라 선택되거나 전송되는 순간 routing table에 따라 결정됩니다.

      따라서 connect는 서버에 여러 IP중 하나와 연결시키는 것과는 아무 상관이 없습니다. 제 글 중 recv 에 대해서 필터링을 한다는 얘기는 recv 상태에서는 모든 UDP 패킷을 받을 수 있으나 송신지가 connect 해둔 주소에서 오는 것외에는 필터링을 한다는 말이었습니다.

  2. 백탄왕 2007.05.08 18:40 신고

    질문하나 해도 될런지요?
    connect를 호출하고 난 후에는 connect 호출된 클라이언트 이외의 패킷들은 recv에서 필터링 된다는 글인것 같은데, 맞습니까? 그렇다면 지금 설명하신게 리눅스 기반에서 말씀하신 듯 한데, 윈도우에서도 똑같이 적용되는지 혹시 아시는지요? (물론 윈속이 아닌 경우를 말씀드리는 것입니다.)
    :) 답변 기다리겠습니다. 감사합니다..

    • 최호진 2007.05.08 20:32 신고

      윈도우에서는 테스트 해보진 않았지만 (환경이 안돼서리..) 버클리 소켓의 기본적인 행동이므로 동작하리라 예상됩니다.

+ Recent posts