[Network] 13. 다양한 입출력 함수들

2023. 5. 28. 21:58

우리는 이때까지 입출력을 할 때 read와 write를 사용했다. read와 write 는 기본 C언어에서 제공하는 함수이다. 이것 말고 sys/socket.h 에서 제공하는 send, recv 함수와 sys/uio.h에서 제공하는 readv, writev 함수에 대해 알아보자.

 

send & recv 입출력 함수

send & recv 함수

- send

#include <sys/socket.h>

ssize_t send(int sockfd, const void * buf, size_t nbytes, int flags);

- recv

#include <sys/socket.h>

ssize_t recv(int sockfd, void * buf size_t nbytes, int flags);

 

send & recv 함수의 옵션과 그 의미

옵션 정보는 | 연산자로 둘 이상을 지정할 수 있다. 

 

MSG_OOB : 긴급 메시지의 전송

OOB (out of band) 는 대역 외 발사라는 의미로 긴급하게 데이터를 보내고자할 때 사용한다. 주의해야할 점은 msg_oob를 사용한다고 소켓이 데이터를 빠르게 보내는 것이 아니라 긴급 상황의 발생을 알릴 뿐이다.

void urg_handler(int signo)
{
	int str_len;
    char buf[BUF_SIZE];
    str_len = recv(recv_sock, buf, sizeof(buf)-1, MSG_OOB);
    buf[str_len] = 0;
    printf("Urgent message : %s \n", buf);
}

MSG_OOB 메시지를 받으면 SIGURG 시그널이 발생한다. 이를 처리하기 위해 signal handling 을 사용한다.

그리고 긴급으로 보낸 메시지의 양에 관계없이 1바이트만 반환이 된다는 것도 알아두자!

Urgent mode 의 동작원리

 

입력 버퍼 검사하기

send, recv 함수의 옵션 중 하나인 MSG_PEEK와 MSG_DONTWAIT 옵션 지정으로 블로킹 되지 않고 데이터의 존재 유무를 검사할 수 있다. MSG_PEEK 옵션 덕분에 버퍼에서 데이터를 소멸시키지 않아도 데이터를 읽을 수 있다. 

str_len = recv(recv_sock, buf, sizeof(buf)-1, MSG_PEEK|MSG_DONTWAIT);

 

readv & writev 입출력 함수

writev 함수의 사용

#include <sys/uio.h>

ssize_t writev(int filedes, const struct iovec * iov, int iovcnt);

struct iovec vec[2];
char buf1[]="ABCDEFG";
char buf2[]="1234567";
int str_len;

vec[0].iov_base = buf1;
vec[0].iov_len = 3;
vec[1].iov_base = buf2;
vec[1].iov_len = 4;

str_len = writev(1, vec, 2);

printf("\nwrite bytes: %d\n, str_len);
return 0;

iov_base에 버퍼의 주소정보를 넣고 iov_len에 크기 정보를 넣는다. 실제 iov_base의 데이터가 iov_len의 길이보다 길더라도 설정한 데이터의 크기 만큼만 전송된다.

 

 

readv 함수의 사용

#include <sys/uio.h>

ssize_t readv(int filedes, const struct iovec * iov, int iovcnt);

writev의 사용법과 같은데 차이점은 iov_base에 입력받을 공간을 지정해주면 된다.

 

readv & writev 함수의 적절한 사용

readv, writev 함수는 여러 정보를 묶어 보낼 수 있기 때문에 함수의 호출 횟수를 줄일 수 있어 효율적이다. 

이는 전송 속도의 향상으로도 이어질 수 있다. 

 

 

recvmsg() & sendmsg()

이 내용은 책에 있는 것은 아니고 교수님께서 추가적으로 알려주신 것이다. 

recvmsg()

#include<sys/socket.h>
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);

 

sendmsg()

#include <sys/socket.h>

ssize_t sendmsg(int sockfd, struct msghdr * msg, int flags);

 

socket I/O functions summary

BELATED ARTICLES

more