소켓 프로그램의 통신 관련 함수 send, sendto, recv, recrfrom의 이해
소켓 프로그래밍에서 데이터를 전송하는 함수인 send()와 sendto()의 차이점
버퍼에 들어 있는 바이트들을 주어진 소켓을 통해 보냅니다. 소켓은 반드시 연결된 상태이어야 합니다. 이 호출이 반환할 때 데이터는 해당 연결을 통해 전송되기 위해 큐에 저장됩니다. 의미는 소켓의 형태에 따라 달라집니다. 스트림 소켓의 경우 데이터는 연결이 정상적으로 닫힌 경우 궁극적으로 전송될 것입니다. 데이터그램 소켓으리 경우 전달에 대한 보장이 없습니다. 그러나 한 번의 send() 호출에 의한 데이터는 결코 여러 recv() 호출로 나우어지지 않습니다. 반환 값은 실제로전송된 바이트의 수를 나타냅니다. send() 함수와 sendto() 함수는 모두 데이터를 소켓으로 전송하는데 사용되는 함수입니다. 하지만, 두 함수의 차이점은 다음과 같습니다.
send() 함수
- Connection-oriented 소켓 (예: TCP) 에서 사용됩니다.
- 소켓이 연결된 상태에서 데이터를 전송합니다.
- 수신자의 주소를 지정하지 않으며, 이미 연결된 상대방에게만 데이터를 전송합니다.
- 원형 : ssize_t send(int sockfd, const void *buf, size_t len, int flags);
- sockfd: 데이터를 전송할 소켓의 파일 디스크립터(Socket File Descriptor).
- buf: 송신할 데이터를 담고 있는 버퍼의 포인터.
- len: 송신할 데이터의 크기.
- flags: 송신에 대한 추가적인 옵션 플래그(예: MSG_DONTWAIT, MSG_NOSIGNAL 등).
- 반환값: 송신된 데이터의 바이트 수. 오류 시 -1을 반환하고 errno 변수에 오류 코드가 설정됩니다.
sendto() 함수
- Connectionless 소켓 (예: UDP) 에서 사용됩니다.
- 데이터를 전송하고자 하는 수신자의 주소를 지정할 수 있습니다.
- 소켓이 연결되지 않은 상태에서 데이터를 전송합니다.
- ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
- sockfd: 데이터를 전송할 소켓의 파일 디스크립터(Socket File Descriptor).
- buf: 송신할 데이터를 담고 있는 버퍼의 포인터.
- len: 송신할 데이터의 크기.
- flags: 송신에 대한 추가적인 옵션 플래그(예: MSG_DONTWAIT, MSG_NOSIGNAL 등).
- dest_addr: 데이터를 수신할 목적지 주소(struct sockaddr 구조체 형태).
- addrlen: 목적지 주소의 크기.
- 반환값: 송신된 데이터의 바이트 수. 오류 시 -1을 반환하고 errno 변수에 오류 코드가 설정됩니다.
따라서, 데이터를 전송하기 전에 소켓의 타입과 상황에 맞는 함수를 선택하여 사용해야 합니다.
네트워크 소켓 프로그래밍에서 recv() 함수와 recvfrom() 함수의 차이점
소켓으로 수신된 지정 크기만큼의 바이트를 지정된 위치에 복사한다. 주어진 소켓은 연결된 상태에 있어야 합니다. 이 호출은 적어도 한 바이트가 반환되거나 또는 연결이 닫힐 때까지 블록됩니다. 반환 값은 가리키고 있는 위치에서 시작하여 실제로 버퍼에 복사된 바이트의 수를 나타냅니다. 의미는 소켓의 형태에 따라 달라집니다. 스트림 소켓의 경우 바이트들은 전송된 순서 그래도 빠짐없이 전달됩니다. 데이터그램 소켓의 경우 각 recv()는 많아야 한 send()로부터의 데이터르 반환하고 순서가 반드시 유지되는 것은 아닙니다. recv() 함수와 recvfrom() 함수는 모두 네트워크 소켓에서 데이터를 수신하는 함수입니다. 그러나 두 함수는 다음과 같은 차이점이 있습니다.
recv() 함수
- recv() 함수는 연결 지향적인 소켓에서 사용됩니다. 이 함수는 소켓으로부터 데이터를 수신하고, 송신자의 주소나 포트 정보는 알 수 없습니다. 이 함수는 데이터의 크기나 송신자의 주소 정보 없이 그저 데이터를 가져올 때 사용됩니다.
- 원형 : ssize_t recv(int sockfd, void *buf, size_t len, int flags);
- sockfd: 데이터를 수신할 소켓의 파일 디스크립터(Socket File Descriptor).
- buf: 수신한 데이터를 저장할 버퍼의 포인터.
- len: 수신할 데이터의 최대 크기.
- flags: 수신에 대한 추가적인 옵션 플래그(예: MSG_DONTWAIT, MSG_WAITALL 등).
- 반환값: 수신한 데이터의 바이트 수. 오류 시 -1을 반환하고 errno 변수에 오류 코드가 설정됩니다.
recvfrom() 함수
- recvfrom() 함수는 비연결 지향적인 소켓에서 사용됩니다. 이 함수는 소켓으로부터 데이터를 수신하면서 송신자의 주소나 포트 정보도 함께 가져올 수 있습니다. 이 함수는 주로 데이터의 크기나 송신자의 주소 정보도 함께 필요한 경우에 사용됩니다.
- 원형 : ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
- sockfd: 데이터를 수신할 소켓의 파일 디스크립터(Socket File Descriptor).
- buf: 수신한 데이터를 저장할 버퍼의 포인터.
- len: 수신할 데이터의 최대 크기.
- flags: 수신에 대한 추가적인 옵션 플래그(예: MSG_DONTWAIT, MSG_WAITALL 등).
- src_addr: 데이터를 송신한 송신지 주소 정보(struct sockaddr 구조체 형태).
- addrlen: 송신지 주소 정보의 크기.
- 반환값: 수신한 데이터의 바이트 수. 오류 시 -1을 반환하고 errno 변수에 오류 코드가 설정됩니다.
따라서, 데이터를 수신할 때, 송신자의 주소나 포트 정보도 필요하다면 recvfrom() 함수를 사용하면 되고, 그렇지 않은 경우에는 recv() 함수를 사용하면 됩니다.