728x90

send & recv

- read / write는 옵션, 특성을 부여할 수 없지만 send / recv는 부여할 수 있음

- send : 데이터 전송

    -> 성공 시 전송된 바이트 수, 실패 시 -1 반환

#include <sys/socket.h>

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

- recv : 데이터 수신

    -> 성공 시 수신한 바이트 수, 실패 시 -1 반환

#include <sys/socket.h>

ssize_t recv(int socket, void *buf, size_t len, int flags);

- flags : 데이터 송수신에 사용되는 옵션 정보

    -> '|(OR)' 연산자를 이용해서 둘 이상을 동시에 지정 가능

    -> 옵션의 종류와 지원 여부는 운영체제별로 차이가 있음

    -> MSG_OOB : OOB 옵션을 줄 수 있음

    -> MSG_PEEK : read 시 입력 버퍼에 있는 데이터가 소멸되지 않음

    -> MSG_DONTROUT : 로컬 상에서만 데이터를 전송하겠다는 옵션

    -> MSG_DONTWAIT : 읽어들일 데이터가 없거나 쓸게 없더라도 block되지 않고 바로 반환

    -> MSG_WAITALL : 요청한 바이트 수만큼 받을때까지 반환되지 않음

 

MSG_OOB

- OUT-OF-BAND 메시지를 전송, 수신할 수 있는 옵션

- OUT-OF-BAND 메시지는 긴급 데이터를 의미하고 긴급 데이터라고 해서 TCP의 기본인 전송 순서를 유지하는 틀을 깨지는 않고 이 메시지가 긴급이라고 알리기 위한 옵션

- OOB 메세지를 운영체제에서 받으면 프로세스에 알려주게 되는데 프로세스에 알려주기 위해 시그널 핸들링 사용

- SIGURG 시그널을 등록

- 긴급으로 보낸 메세지의 양에 상관없이 1바이트만 반환해서 긴급이라는 것을 알려줌

int main(int argc, char *argv[])
{
	...;
	struct sigaction act;
	
	act.sa_handler=urg_handler;
	sigemptyset(&act.sa_mask);
	act.sa_flags=0; 
	
	acpt_sock=socket(PF_INET, SOCK_STREAM, 0);
	...;
	fcntl(recv_sock, F_SETOWN, getpid()); 
    // recv_sock의 소유자를 현재 프로세스로 변경
    // recv_sock에 대한 시그널이 발생했을 때 현재 프로세스로 받을 것임을 명시
	state=sigaction(SIGURG, &act, 0);
	// 시그널 등록
    
	while((str_len=recv(recv_sock, buf, sizeof(buf), 0))!= 0) 
	{
		if(str_len==-1) {
			continue;
        	}
		buf[str_len]=0;
		puts(buf);
	}
	close(recv_sock);
	close(acpt_sock);
	return 0; 
}

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);
}

 

728x90

+ Recent posts