Задать вопрос
@Jeboxa-developer
Начинающий разработчик

Как работать с сокетами на с++?

Добрый день, мне нужна консультация.

Я не много запутался с сетевым программированием.

Я написал чат:
сервер

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <iostream>

void error(const char *msg) 
{
    perror(msg); 
    exit(1);
}

int main(int argc, char const *argv[])
{
    if (argc < 2)
    {
        fprintf(stderr, "Port didd't provided. Program terminated\n");
        exit(1);
    }

    int sockfd, newsockfd, portnumber, temp;
    char buffer[255];
    struct sockaddr_in server_addr, client_addr;
    socklen_t client_len;

    sockfd = socket(AF_INET, SOCK_STREAM, 0); // 0 = tcp    
    if (sockfd < 0)
    {
        error("Error opening socket");
    }

    memset(&server_addr, 0, sizeof server_addr);
    portnumber = atoi(argv[1]); 
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(portnumber);

    if (bind(sockfd, (struct sockaddr*) &server_addr, sizeof(server_addr)) < 0)
    {
        error("Binding failed");
    }
    
    listen(sockfd, 5);
    client_len = sizeof(client_addr);

    newsockfd = accept(sockfd, (struct sockaddr*) &client_addr, &client_len);

    if (newsockfd < 0)
    {
        error("Error on accept");
    }
    
    while (1)
    {
        memset(buffer, 0, 255);
        temp = read(newsockfd, buffer, 255); 
        if (temp < 0)
        {
            error("Error on reading");
        }        
        printf("client : %s\n", buffer);

        memset(buffer, 0, 255);
        std::cin.getline(buffer, 255);
        temp = write(newsockfd, buffer, strlen
        (buffer));
        if (temp < 0)
        {
            error("Error on writting");
        }
        if (int i = strncmp("bye", buffer, 3) == 0)
        {
            break;
        }
    }
    close(newsockfd);
    close(sockfd);
    return 0;
}


клиент

// argv[0] - filename
// argv[1] - server_ipaddres
// argv[2] - portnumber


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h> // hostent struct
#include <iostream>
#include <arpa/inet.h>

void error(const char *msg) 
{
    perror(msg); 
    exit(1);
}

int main(int argc, char const *argv[])
{
    int sockfd, portnumber, temp;
    struct sockaddr_in server_addr;

    char buffer[255];
    
    if (argc < 2)
    {
        fprintf(stderr, "usage %s hostname port\n", argv[0]);
        exit(1);
    }    

    portnumber = atoi(argv[1]);
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        error("Error opening socket");
    }

    portnumber = atoi(argv[1]); 
    server_addr.sin_family = AF_INET;
    inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr);
    server_addr.sin_port = htons(portnumber);

    if (connect(sockfd, (struct sockaddr*) &server_addr, sizeof(server_addr)) < 0)
    {
        error("Connection failed");
    }
    
    while (1)
    {
        memset(buffer, 0, 255);
        std::cin.getline(buffer, 255);

        temp = write(sockfd, buffer, strlen(buffer));
        if (temp < 0)
        {
            error("Error on writting");
        }

        memset(buffer, 0, 255);
        temp = read(sockfd, buffer, 255); 
        if (temp < 0)
        {
            error("Error on reading");
        }
        printf("server : %s\n", buffer);

        if (int i = strncmp("bye", buffer, 3) == 0)
        {
            break;
        }       
        
    }
    close(sockfd);
    return 0;
}



Но я не использовал и не создавал структуры sockaddr, я не использовал функцию getaddrinfo() и не совсем понимаю зачем это. Я так понял: мой код - это то как писали раньше. А структуру и функцию, которую я написал сверху - это нововедение. Или я что-то не понимаю.
  • Вопрос задан
  • 464 просмотра
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 2
@anikavoi
Уважаемый,
У вас очень сумеречное понимание сокетов.
1. При чем тут "Веб" из заголовка вопроса? Это обычные TCP. WebSocket это совершенно другое, загляните в документацию.
2. "я не использовал и не создавал структуры sockaddr" - мои глаза меня обманывают?
Без sockaddr вы не смогли бы забиндить порт в сервере, и определить адрес\порт назначения в клиенте, не говоря о протоколе.
3. "я не использовал функцию getaddrinfo()" - круто!!! Вау!! ... и что?
Функция getaddrinfo(3) объединяет действия функций getipnodebyname(3), getipnodebyaddr(3), getservbyname(3) и getservbyport(3) в одном интерфейсе. Функция getaddrinfo(3) создает одну или несколько структур адресов сокета, которые в дальнейшем могут быть использованы в вызовах функций bind(3) или connect(3) для создания сокета клиента или сервера.

4. "А структуру и функцию, которую я написал сверху - это нововедение." - КАКУЮ СТРУКТУРУ??? КАКУЮ ФУНКЦИЮ??? void error(const char *msg) - это??? Это потрясающее нововведение! Нобелевскую премию мира и нобелевскую премию по литературе вам! Их все равно сейчас дают людям далеким от мира и от литературы.
5. "Или я что-то не понимаю." - ни-че-го. Ничего вы не понимаете. Прочтите, наконец, документацию по программированию сокетов, ПРЕЖДЕ чем задават вопрос, в котором совершенно непонятно о чем вопрос.
... а еще лучше - бросайте программирование.
Ответ написан
Комментировать
HemulGM
@HemulGM
Delphi Developer, сис. админ
Можно не использовать ни структуры sockaddr, ни getaddrinfo(), ни getipnodebyname() явно и даже можно вообще не знать о них. Они используются в любом случае где-то глубже внутри, т.к. это низкоуровневые, базовые методы работы с сокетами и с сетевыми протоколами в целом.
Как уже заметили выше, то что вы используете - это не веб-сокеты. Веб-сокеты это более высокоуровневый протокол, чем обычные сокеты.

P.S. скопированный код из сети не может считаться написанным вами. (хоба)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы