반응형
  • Linux에서의 send & recv
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags);

- sockfd: 데이터 전송 대승과의 연결을 의미하는 socket의 file descriptor

- buf: 전송할 데이터를 저장하고 있는 버퍼의 주소값

- len: 전송할 바이트 수 

- flags: 데이터 전송 시 옵션 정보

#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t len, int flags);

- sockfd: 데이터 수신 대상과의 연결을 의미하는 socket file descriptor

- buf: 수신된 데이터를 저장할 버퍼의 주소값

- len: 수신할 수 있는 최대 바이트 수

- flags: 데이터 수신 시 적용할 옵션 정보

 

  • 옵션 정보 (| 를 이용하여 둘 이상을 함께 전달 가능)
옵션 의미 send recv
MSG_OOB 긴급 데이터(out-of-band data)의 전송을 위한 옵션 * *
MSG_PEEK 입력버퍼에 수신된 데이터의 존재유무 확인을 위한 옵션   *
MSG_DONTROUTE 데이터 전송과정에서 라우팅 테이블을 참조하지 않을 것을 요구하는 옵션, 따라서 로컬 네트워크 상에서 목적지를 찾을 때 사용되는 옵션 *  
MSG_DONTWAIT 입출력 함수 호출과정에서 블로킹 되지 않을 것을 요구하기 위한 옵션, non-blocking IO의 요구에 사용되는 옵션 * *
MSG_WAITALL 요청한 바이트 수에 해당하는 데이터가 전부 수신될 때까지 호출된 함수가 반환되는 것을 막기 위한 옵션   *

 


  • MSG_OOB: 긴급 메시지의 전송

- out-of-band data라는 긴급 메세지의 전송을 위해 메시지의 전송방법 및 경로를 달리 함

- MSG_OOB의 긴급 메시지를 수신하면 운영체제는 SIGURG 시그널을 발생시켜 프로세스가 등록한 시그널 핸들로가 호출

- fcntl(recv_sock, F_SETOWN, getpid());  // file descriptor의 컨트롤에 사용

: file descriptor recv_sock이 가리키는 socket에 의해 발생하는 SIGURG 시그널을 처리하는 프로세스를 getpid 함수가 반환하는 ID의 프로세스로 변경시키겠다

- getpid: 이 함수를 호출한 프로세스의 ID를 반환하는 함수

 

// oob_send.c

// oob_recv.c

// 실행창

 

- TCP는 전혀 다른 통신 경로로 전송되는 데이터를 뜻하는 out-of-band data를 위한 별도의 통신경로를 제공하지 않고 TCP의 Urgent mode를 이용해 데이터를 전송

- MSG_OOB 옵션을 추가해도 더 빨리 데이터가 전송되지 않음

- 시그널 핸들러를 이용해 읽히는 데이터는 1바이트이며 나머지는 일반적인 입력함수의 호출을 통해 읽힘

 

  • Urgent mode

- 데이터의 전송에서 전송순서가 유지되면서 데이터를 수신하는 대상에게는 데이터의 처리를 재촉

- 빠른 전송 속도를 보장하진 않지만 긴급 메시지가 전송되었음이 시그널 핸들러를 통해 인지됨

 

  • MSG_OOB 옵션의 데이터 전송 과정

send(sock, "890", strlen("890"), MSG_OOB);

긴급 메시지 전송단계의 출력버퍼

- offset 3의 위치가 urgent pointer로 지정되어 긴급 메시지의 마지막 문자열의 offset + 1의 위치를 가리키면서 상대 호스트에게 urgent pointer가 가리키는 offwet의 바로 앞에 존재하는 것이 긴급 메시지임을 알림

 

- 데이터 전송을 위해 구성되는 TCP 패킷의 구조

URG 설정 패킷

- TCP header에 URG=1 : 긴급 메시지 존재

- TCP header에 urgent pointer=5 : urgent pointer의 위치가 offset 5의 위치

- 데이터를 수신하는 상대 호스트에서는 urgent pointer의 앞 1바이트를 제외하고는 나머지는 일반적인 입려함수의 호출로 읽음

 

offset: 기본이 되는 위치를 바탕으로 상대적 위치를 표현하는 것
ex) 실제 3번지를 기준으로 offset 부여 -> 실제 4번지: offset 1
때문에 일반적인 주소와 달리 항상 0에서부터 시작

 

  • MSG_PEEK: 입력버퍼 검사하기

- MSG_PEEK

: MSG_DONTWAIT 옵션과 함께 설정되어 입력버퍼에 수신된 데이터가 존재하는지 확인하는 용도

: MSG_PEEK 옵션을 설정하고 recv 함수를 호출하면 입력버퍼에 존재하는 데이터가 읽혀지더라도 데이터가 지워지지 않음, MSG_DONTWAIT 옵션과 함께 사용해 입력버퍼에 데이터가 존재하지 않더라도 블로킹(반환안되는 상태) 되지 않도록 함

 

// peek_recv.c

- 입력버퍼의 데이터를 지우기 위해 옵션을 설정하지 않은 recv 함수를 한번 더 호출

// peek_send.c

// 실행창

- 한번 전송한 데이터가 두 번 읽혀짐

반응형

+ Recent posts