Способ использования необработанных сокетов

#c #sockets #networking #raw-sockets

#c #сокеты #сетевое взаимодействие #необработанные сокеты

Вопрос:

Я впервые использую необработанные сокеты, поэтому извините меня, если мой вопрос демонстрирует серьезную нехватку знаний в этой области. Моя цель — создать клиент-серверную программу, использующую необработанные сокеты, где клиент может отправлять строку на сервер, а сервер может отправлять ответ. Мои коды следующие:

 /* server.c */
#include "../cn.h"
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

int main(int argc, char const *argv[]) {
    int sfd = socket(AF_INET, SOCK_RAW, 253);
    if (sfd < 0) {
        perror("Could not create socket");
        exit(0);
    }
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    if (bind(sfd, (struct sockaddr*)amp;addr, sizeof(addr)) < 0) {
        perror("Could not bind");
    }
    int nsfd = accept(sfd, NULL, NULL);
    if (nsfd < 0) {
        perror("Could not accept");
        exit(0);
    }
    char buffer[20];
    int sz;
    while (1) {
        if ((sz = read(nsfd, buffer, 20)) < 0) {
            perror("Could not read");
        } else {
            buffer[sz] = '';
            strcat(buffer, " form server");
            if (write(nsfd, buffer, strlen(buffer)) < 0) {
                perror("Could not send");
            }
        }
    }
    return 0;
}
  

Клиентский код:

 #include "../cn.h"
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

int main(int argc, char const *argv[]) {
    int sfd = socket(AF_INET, SOCK_RAW, 253);
    if (sfd < 0) {
        perror("Could not create socket");
        exit(0);
    }
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    if (connect(sfd, (struct sockaddr*)amp;addr, sizeof(addr)) < 0) {
        perror("Could not connect");
        exit(0);
    }
    char buffer[20];
    int sz;
    while (1) {
        scanf("%[^n]s", buffer);
        while (getchar() != 'n')
            ;
        if (write(sfd, buffer, strlen(buffer)) < 0) {
            perror("Could not write");
        } else
        if ((sz = read(sfd,buffer, 20)) < 0) {
            perror("Could not read");
        } else {
            buffer[sz] = '';
            printf("Reading: %sn", buffer);
        }
    }
    return 0;
}
  

Всякий раз, когда я пытаюсь запустить программы, он выдает ошибку в самый момент создания сокета:

 Could not create socket: Operation not permitted
  

Мои вопросы:

  1. Чего мне не хватает в этом случае? Почему эта операция не разрешена?

  2. Хотя это широкий вопрос, но как использовать необработанные сокеты с пользовательским идентификатором протокола?

  3. Есть ли какой-либо хороший материал, доступный для использования необработанных сокетов с пользовательским протоколом?

Комментарии:

1. Являетесь ли вы root? «Только процессам с эффективным идентификатором пользователя 0 или возможностью CAP_NET_RAW разрешено открывать необработанные сокеты». от linux.die.net/man/7/raw

2. @user6556709 okk ..запуск его с помощью sudo решил проблему создания. Но теперь он говорит, что принятие не поддерживается. Итак, я попытался использовать функции sendto () и recvfrom(). Теперь возникает другая проблема. Всякий раз, когда я отправляю какую-либо строку со стороны клиента, Сервер считывает случайную строку (в данном случае заглавную E) бесконечное количество раз! Пожалуйста, пролейте на это немного света.

3. Вы не можете привязать или принять необработанный сокет. Но вы должны использовать ioctl для установки параметра IP_HDRINCL. И при чтении вы получаете полный IP-фрейм, включая полный IP-заголовок. Как описано на linux.die.net/man/7/raw