Skip to content

Study : CPP : send, recv

Jiwon-Woo edited this page Apr 4, 2022 · 2 revisions
항목 내용
일자 2022.04.03
작성자 jwoo
제목 webserv 허용함수 - send, recv
한줄요약 send and receive a message from a socket


webserv 허용함수

send


NAME

send a message from a socket


SYNOPSIS

#include <sys/socket.h>

ssize_t	send(int socket, const void *buffer, size_t length, int flags);

ssize_t	sendmsg(int socket, const struct msghdr *message, int flags);

ssize_t	sendto(int socket, const void *buffer, size_t length, int flags, const struct sockaddr *dest_addr, socklen_t dest_len);

DESCRIPTION

send(), sendto(), sendmsg() 함수는 데이터를 다른 소켓으로 전송하는 데 사용하는 함수입니다. send()는 소켓이 연결된 상태일 때만 사용할 수 있지만 sendto()와 sendmsg()는 연결 여부와 상관없이 사용할 수 있습니다.

만약 소켓에 전송할 데이터를 보관할 수 있는 공간이 남아있지 않으면, non-blocking I/O 모드가 아닌 한, 일반적으로 소켓은 block 됩니다. 이런 상황에서는 select 함수를 호출하여 더 많은 데이터를 보낼 수 있는 타이밍을 찾고, 그 타이밍에 send() 함수를 호출할 수 있게 됩니다.

send()의 첫번째 인자 socket 은 connect()와 accept()에 의해 연결된, 데이터를 수신받을 대상과 연결된 소켓의 fd 값입니다. 두번째 인자 buffer 는 전송할 메세지이며, 세번째 인자 length 는 전송할 메세지의 길이입니다. 마지막 flag 는 전송할 데이터 또는 읽는 방법에 대한 옵션을 의미하는데, 값이 0이면 write(socket, buffer, length) 함수와 동일하게 작동합니다.

flags 매개변수는 다음 중 하나 이상을 포함할 수 있습니다:

#define MSG_OOB        0x1  /* process out-of-band data */
#define MSG_DONTROUTE  0x4  /* bypass routing, use direct interface */
  • MSG_OOB : 긴급 데이터(“out-of-band” data)를 보내는 데 사용하는 옵션입니다. SOCK_STREAM 유형의 소켓과 같이 해당 개념이 존재하는 소켓에서 사용할 수 있습니다.
  • MSG_DONTROUTE : 데이터 전송 시 라우팅 테이블(라우터에 있음)을 참조하지 않습니다.gateway를 통하지 않고 직접 상대시스템으로 전송하는 옵션입니다.

RETURN VALUES

성공적으로 완료되면 전송된 바이트 수가 반환됩니다. 그렇지 않으면 -1이 반환되고 전역 변수 errno가 오류에 대한 내용이 저장됩니다.



recv


NAME

receive a message from a socket


SYNOPSIS

#include <sys/socket.h>

ssize_t	recv(int socket, void *buffer, size_t length, int flags);

ssize_t	recvfrom(int socket, void *restrict buffer, size_t length, int flags, struct sockaddr *restrict address, socklen_t *restrict address_len);

ssize_t	recvmsg(int socket, struct msghdr *message, int flags);

DESCRIPTION

recvfrom(), recvmsg() 함수는 소켓에서 메시지를 수신하는 데 사용되며, sendto()와 sendmsg() 함수와 마찬가지로 연결 지향 여부에 관계없이 사용할 수 있습니다. 반면, recv() 함수는 일반적으로 connect()로 연결된 소켓에서만 사용됩니다.

recv()의 첫번째 인자 socket 은 connect()와 accept()에 의해 연결된, 데이터를 수신받을 대상과 연결된 소켓의 fd 값입니다. 두번째 인자 buffer 는 데이터를 수신하여 저장할 전송할 곳이며, 세번째 인자 length 는 수신할 데이터의 길이입니다. 마지막 flag 는 읽을 데이터 또는 읽는 방법에 대한 옵션을 의미하는데, 값이 0이면 read(socket, buffer, length) 함수와 동일하게 작동합니다.

세 함수 모두 성공적으로 완료되면 수신받은 데이터 길이를 반환합니다. 데이터가 너무 길어서 인자로 주어진 버퍼에 맞지 않으면 메시지를 수신한 소켓 유형(socket() 참조)에 따라 초과 바이트가 삭제될 수 있습니다. buffer_len 을 넘어서는 데이터를 수신하고 싶다면 반복문을 통해 데이터의 끝에 도달할 때까지 recv() 함수로 데이터를 수신해와야합니다.

소켓에서 가져올 수 있는 메시지가 없으면 소켓이 non-blocking 방식이 아닌 한 메시지가 도착하기까지 대기합니다. non-blocking 소켓인 경우 기다리지 않고 값 -1을 반환하며, 외부 변수 errno가 EAGAIN으로 설정됩니다. 수신할 수 있는 메시지가 없고 소통하는 소켓이 순서대로 종료를 수행한 경우에는 0이 반환됩니다.

일반적으로 recv()는 전체 수신 데이터를 기다리지 않고, 요청된 양까지 사용 가능한 데이터를 반환합니다.

select 함수는 더 많은 데이터를 받아올 수 있는 타이밍을 찾고, recv() 함수를 호출할 수 있게 합니다.

recv() 함수의 flags 인수는 다음 중 하나 이상의 값으로 구성됩니다:

  • MSG_OOB : out-of-band 데이터를 처리합니다. out-of-band 데이터는 일반 데이터 스트림에서 수신되지 않는 긴급 데이터입니다.
  • MSG_PEEK : 데이터 수신 작업이 큐에서 데이터를 제거하지 않은 채 수신 큐의 시작 부분에서 데이터를 반환하도록 합니다.
  • MSG_WAITALL : 전체 요청이 처리될 때까지 작업을 block 합니다. 그러나 signal이 포착되거나, 오류 또는 연결 끊김이 발생하거나, 수신할 다음 데이터가 반환된 데이터 유형과 다른 경우 recv()은 요청한 것보다 적은 데이터를 반환할 수 있습니다.

RETURN VALUES

성공시 수신된 데이터의 바이트 수를 반환하고, 오류 발생시 -1을 반환합니다. TCP 소켓의 경우, 소통하는 대상이 연결의 절반을 종료했을 때 0을 반환합니다.


// uploaded 220403