UDP-сокеты в C - PullRequest
       42

UDP-сокеты в C

5 голосов
/ 02 декабря 2009

Я работаю над проблемой домашнего задания для класса.Я хочу запустить UDP-сервер, который прослушивает запрос файла.Он открывает файл и отправляет его обратно запрашивающему клиенту с UDP.

Вот код сервера.

    // Create UDP Socket
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        perror("Can't create socket");
        exit(-1);
    }

    // Configure socket
    memset(&server, 0, sizeof server);
    server.sin_family = AF_INET; // Use IPv4
    server.sin_addr.s_addr = htonl(INADDR_ANY); // My IP
    server.sin_port = htons(atoi(argv[1])); // Server Port

    // Bind socket
    if ((bind(sockfd, (struct sockaddr *) &server, sizeof(server))) == -1) {
        close(sockfd);
        perror("Can't bind");
    }

    printf("listener: waiting to recvfrom...\n");
    if (listen(sockfd, 5) == -1) {
        perror("Can't listen for connections");
        exit(-1);
    }

while (1) {
    client_len = sizeof(struct sockaddr_in);
    newsockfd = accept(sockfd, (struct sockaddr*)&client,&client_len);

    if (newsockfd < 0) {
        perror("ERROR on accept");
    }

    // Some how parse request
    // I do I use recv or recvfrom?
    // I do I make new UDP socket to send data back to client?

    sendFile(newsockfd, filename);

    close(newsockfd);
}

close(sockfd);

Я немного заблудился, как мне получить данные от клиента?А как мне сделать новое UDP-соединение обратно к клиенту?

Ответы [ 4 ]

12 голосов
/ 19 октября 2011

Я написал сервер-клиент UDP на C , где клиент отправляет регистрационный номер, а сервер дает имя в качестве обратной связи.

SERVER

0. Variable initialization
1. sock()
2. bind()
3. recvfrom()
4. sendto()

КЛИЕНТ

0. gethostbyname()
1. sock()
2. bzero()
4. sendto()
5. recvfrom()

Надеюсь, это поможет. Вы можете найти пример кода здесь сервер / клиент udp

12 голосов
/ 02 декабря 2009

Чем UDP отличается от TCP:

  • ориентированный на сообщения, а не на поток. Вы не читаете / не пишите и не отправляете / записываете. Вы отправляете / recvfrom. Размер сообщения ограничен 64К. Каждый вызов recvfrom получает одно сообщение, отправленное вызовом sendto. Если recvfrom передает буфер, размер которого меньше размера сообщения, остальная часть сообщения исчезает навсегда.

  • нет соединений. Поэтому не слушайте / принимайте / подключайтесь. Вы отправляете сообщение на определенный адрес / порт. Когда вы получаете сообщение (на адрес / порт, к которому привязан ваш сокет), вы получаете источник входящего сообщения в качестве выходного параметра для recvfrom.

  • без гарантий. Сообщения могут быть отброшены или получены не по порядку. Если я правильно помню, они не могут быть усечены, хотя.

Последнее слово предостережения - вы можете заново изобретать TCP через UDP. В этом случае остановитесь и вернитесь к TCP.

2 голосов
/ 02 декабря 2009

accept используется только для сокетов, ориентированных на соединение (STREAM). UDP не потоковый, ориентированный, поэтому нет никаких соединений, и вы не можете использовать accept (2) - он вернет EOPNOTSUPP.

Вместо этого вы просто читаете пакеты непосредственно из привязанного сервисного сокета (обычно используя recvfrom (2), чтобы вы могли определить, откуда вы пришли, хотя вы можете использовать recv или просто читать, если вам все равно), после чего вы можете отправлять пакеты назад, используя один и тот же сокет (и обычно используя sendto (2))

1 голос
/ 02 декабря 2009

Имейте в виду, что UDP не имеет соединения. Он только отправляет пакеты и не подходит для отправки файлов - если только весь контент не помещается в один пакет UDP.

Если вы все равно хотите отправлять / получать UDP-пакеты, просто позвоните sendto / recvfrom с соответствующими адресами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...