현생/TCP 소켓 프로그래밍

13. 다양한 입출력 함수 [TCP/IP][C][LINUX]

푸더기 2022. 2. 5. 12:15
반응형

 

write & read

지금까지 써온 입출력 함수입니다. 리눅스에선 소켓을 파일처럼 다룰 수 있다는 점을 이용해 파일 입출력 함수를 사용해왔습니다.

#include<unistd.h>

//입력 함수 - success: 전달한 바이트 수, fail: -1
ssize_t write(int fd, const void *buf, size_t nbytes);

//출력 함수 - success: 수신한 바이트 수(EOF 전송 시 0), fail: -1
ssize_t read(int fd, void *buf, sized_t nbytes);

 

send & recv

#include<sys/socket.h>

//입력 함수 - success: 전송된 바이트 수, fail: -1
ssize_t send(int sockfd, const void *buf, size_t nbytes, int flags);

//출력 함수 - success: 수신한 바이트 수(EOF 전송 시 0), fail: -1
ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags);

윈도우의 send 함수와 recv 함수와 차이가 없어서 이식성이 좋습니다. 마지막 매개변수인 flags에는 데이터 송수신시 적용할 옵션정보가 전달됩니다. 각 옵션들은 OR연산자( | 연산자 )를 통해 둘 이상을 함께 전달할 수 있습니다.

옵션 의미 send recv
MSG_OOB 긴급 데이터 전송 O O
MSG_PEEK 입력버퍼에 수신된 데이터의
존재유무 확인
  O
MSG_DONTROUTE 데이터를 전송할 때
로컬 네트워크상에서만 목적지를 찾음
O  
MSG_DONTWANT 입출력 함수 호출과정에서
블로킹 되지 않음
O O
MSG_WAITALL 요청된 바이트 수에 해당하는 데이터가
전부 수신할 때까지 반환되지 않음
  O

단, 위 옵션의 지원여부는 운영체제마다 조금씩 차이가 날 수 있습니다.

 

 

readv & writev

#include<sys/uio.h>

//입력함수
ssize_t writev(int filedes, const struct iovec * iov, int iovcnt);

//출력함수
ssize_t readv(int filedes, const struct iovec * iov, int iovcnt);

//iovec 구조체
struct iovec{
	void * iov_base; //버퍼의 주소 정보
    size_t iov_len;  //버퍼의 크기 정보
}

writev와 readv는 데이터를 모아서 전송하고, 모아서 수신하는 기능의 함수입니다.  즉 writev를 사용하면 여러 버퍼에 있는 데이터를 한번에 전송할 수 있고 readv는 데이터를 여러 버퍼에 나눠서 수신할 수 있습니다.

iovec 구조체는 전송할 데이터가 저장돼있는 버퍼의 주소값과 실제 전송할 데이터의 크기 정보를 담도록 정의되어 있습니다. 즉 writev와 readv의 2번째 인자에는 버퍼의 정보가 배열로 들어가게 됩니다.

 

writev에서 2번째 인자의 첫 번째 버퍼 정보가 {"Hello, ",7} 두 번째 버퍼정보가 {"World",5}를 담고 있다면 "Hello, World"가 전송됩니다.

readv에서 2번째 인자의 첫 번째 버퍼 정보가 {BUF1, 7} 두 번째 버퍼 정보가 {BUF2, 5}를 담고 있다면 "Hello, World"가 전송됐을 때 BUF1에는 "Hello, "가 저장되고 BUF2에는 "World"가 저장됩니다.

 

write함수, read함수와 비교했을 때 여러 데이터를 한번에 보내야할때는 물론 더 효율이 좋고 한개의 데이터를 보낼때도 같은 효율을 보이므로 readv함수와 writev함수는 사용할 수 있다면 사용하는 것이 좋습니다.

반응형