Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

<a href="/modules/moniwiki/wiki.php/manSearch?google=none&name=recvfrom">recvfrom</a>(2)

1장. recvfrom(2)

차례
1.1절. 사용법
1.2절. 설명
1.3절. 반환값
1.4절. 에러
1.5절. 예제

소켓(:12)으로 부터 메시지를 읽어들인다.


1.1절. 사용법

#include <sys/socket.h>

#include <sys/types.h>

int recvfrom(int s, void *buf, size_t len, int flags, 
     struct sockaddr *from, socklen_t *fromlen); 
		


1.2절. 설명

이 함수는 소켓으로 부터 데이타를 읽어들이기 위해서 사용되며, 연결지향(:12)이든지 아니든지간에 데이타를 읽어들일수 있다.

s는 소켓지정자이며, buf로 데이타를 읽어들이게 된다. 이때 읽어들일 데이타의 최대크기는 len을 통해서 결정된다.

from는 메시지의 원주소를 나타내는데, 연결지향소켓이 아닌경우에만 채워진다(연결지향소켓일 경우 accept할때 확인이 가능함으로 굳이 인자를 써서 원주소를 읽어들일 필요가 없다). fromlen은 주소구조체의 크기이다.

flags는 다음중 선택해서 지정할수 있다.

MSG_OOB

out-of-band data를 이 개념을 지원하는 소켓으로 보낸다.

MSG_DONTROUTE

패킷을 전송하는데 게이트웨이를 사용하지 않고 직접 연결된 네트워크를 통해서 호스트로 보낸다. 이것은 diagnostic 혹은 routing 프로그램에 의해서만 사용한다.

MSG_DONTWAIT

non-blocking를 가능케 한다.

MSG_NOSIGNAL

다른 한쪽의 소켓의 연결이 끊겼을때, 소켓으로부터 발생하는 스트림상의 SIGPIPE를 보내지 않도록 요구한다. 그러나 EPIPE에러는 여전히 반환된다.


1.3절. 반환값

성공할경우 0을 실패했을경우에는 -1을 반환하며, 적당한 errno 값을 설정한다.


1.4절. 에러

EBADF

s 가 유효한 기술자가 아니다.

ENOTSOCK

s 가 소켓이 아닌 파일일경우

EFAULT

실제하지 않는 사용자 공간주소가 매개변수로 지정되었다.

EINTR

신호발생으로 인하여 인터럽트가 걸렸다.

EPIPE

연결된 소켓이 깨졌다. MSG_NOSIGNAL이 설정되어 있지 않을 경우 프로세스는 SIGPIPE신호를 받게 된다.


1.5절. 예제

#include <sys/socket.h>

#include <sys/stat.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
    int server_sockfd, client_sockfd;
    int client_len, n;
    char buf[80];
    struct sockaddr_in clientaddr, serveraddr;

    client_len = sizeof(clientaddr);

    if ((server_sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
    {
        perror("socket error : ");
        exit(0);
    }
    bzero(&serveraddr, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serveraddr.sin_port = htons(atoi(argv[1]));

    bind (server_sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
    listen(server_sockfd, 5);

    while(1)
    {
        memset(buf, 0x00, 80);
        client_sockfd = accept(server_sockfd, (struct sockaddr *)&clientaddr,
                            &client_len);

        if ((n = recvfrom(client_sockfd, buf, 80, 0, NULL, &client_len)) <= 0)
        {
            close(client_sockfd);
            continue;
        }
        sendto(client_sockfd,(void *)buf, 80, 0,
                        NULL, client_len);
        close(client_sockfd);
    }
}