Простейшая реализация клиент-серверного консольного приложения через сокеты на с++

Вопросы написания собственного программного кода (на любых языках)

Модератор: Olej

Аватара пользователя
Olej
Писатель
Сообщения: 16753
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Простейшая реализация клиент-серверного консольного приложения через сокеты на с++

Непрочитанное сообщение Olej » 19 сен 2022, 12:54

PaiMeiPetrovich писал(а):
18 сен 2022, 18:31
socket_serv.cpp
Сервер ваш, пока, даже просто не компилируется:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/TCPIP-сервер/С++$ c++ socket_serv.cpp -o socket_serv
socket_serv.cpp: In function ‘int main()’:
socket_serv.cpp:64:1: error: expected ‘}’ at end of input
   64 | }
      | ^
socket_serv.cpp:21:1: note: to match this ‘{’
   21 | {
      | ^
В строке 28 нужно добавить: }

Аватара пользователя
Olej
Писатель
Сообщения: 16753
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Простейшая реализация клиент-серверного консольного приложения через сокеты на с++

Непрочитанное сообщение Olej » 19 сен 2022, 13:14

Olej писал(а):
19 сен 2022, 11:48
Я специально не стал добавлять синхронизацию вывода приглашения "Please enter the line!" ... (Потому что у вас достаточно искусственные условия задачи, когда 2 части должны выполняться как-раз последовательно, тут не нужны потоки и параллельность).
Если вам очень хочется иметь приглашение к вводу, то его запрос проще перенести в поток, который после запроса ожидает заполненный буфер:

Код: Выделить всё

void    dosth() {
    while(true) {
        std::cout << "Please enter the line!" << std::endl;        
        mx.lock();
        cv.wait(mx, []{return ready;});        
        std::cout << "Hello FROM DOSTH: " << buf << std::endl;
        ready = false;        
        mx.unlock();
    }
}
Вот:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/TCPIP-сервер/С++$ ./threads
Please enter the line!
123
Hello FROM DOSTH: 123
Please enter the line!
12345
Hello FROM DOSTH: 12345
Please enter the line!
1234567890987654321
Hello FROM DOSTH: 1234567890
Please enter the line!
^C

Аватара пользователя
Olej
Писатель
Сообщения: 16753
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Простейшая реализация клиент-серверного консольного приложения через сокеты на с++

Непрочитанное сообщение Olej » 19 сен 2022, 16:00

Olej писал(а):
19 сен 2022, 12:54
Сервер ваш, пока, даже просто не компилируется:
Переделал я ваш TCP клиент + сервер...
Общая часть (чтобы на повторять дважды, не плодить объём):

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/TCPIP-сервер/С++$ cat socket_common.cc 
#include <iostream>
#include <cstring>
#include <cerrno>
#include <unistd.h>
#include <arpa/inet.h>

using namespace std;

#define BUFFSIZE 40 // 2048
#define DEFAULT_PORT 16555       // Указываем TCP порт

void errx(const char *msg) {    // диагностика ошибки и завершение ...
    perror(msg);
    exit(errno);
}
Клиент:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/TCPIP-сервер/С++$ cat socket_client.cc 
#include "socket_common.cc"

#define SERVER_IP "127.0.0.1"    // Укажите IP-адрес сервера

int main() {
    while (true) {
        int sockfd; // создаем сокет для отправки данных
        if (-1 == (sockfd = socket(AF_INET, SOCK_STREAM, 0)))
            errx("Create socket error");
        struct sockaddr_in servaddr;
        bzero(&servaddr, sizeof(struct sockaddr_in));
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(DEFAULT_PORT);
        inet_aton(SERVER_IP, &servaddr.sin_addr);
        // коннектимся к серверу
        if (-1 == connect(sockfd, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in)))
            errx("Connect error");
        // далее простейшие манипуляции с отправкой и получением данных
        printf("Please input: ");
        string msg;
        getline(cin, msg);    
        int rc = write(sockfd, msg.c_str(), strlen(msg.c_str()) + 1);
        if (rc < 0) {
            perror("write data failed");
            continue;
        }
        char buff[BUFFSIZE + 1] = "";
        rc = read(sockfd, buff, BUFFSIZE);
        if (rc > 0)
            cout << "Recv: " << buff << endl;
        else { 
            perror( "read data failed" );
            continue;            
        }
        close(sockfd);
    }
    return 0;
}
Сервер:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/TCPIP-сервер/С++$ cat socket_serv.cc 
#include <csignal>
#include "socket_common.cc"

int sockfd;                               // прослушивающий сокет

void stopServerRunning(int p) {
    close(sockfd);
    cout << endl << "Server finished" << endl;     
    exit(0);
}

int main() {
    if (-1 == (sockfd = socket(AF_INET, SOCK_STREAM, 0)))
        errx("Create socket error");
    signal(SIGINT, stopServerRunning);    // выключение сервера при вводе Ctrl + C
    int rc;
    if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &rc, sizeof(rc)) != 0)
        errx("Set socket option failed");
    struct sockaddr_in servaddr;          // структура TCP адреса
    bzero(&servaddr, sizeof(servaddr));   // инициализация адреса
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(DEFAULT_PORT);
    // подключаемся к порту
    if (-1 == bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)))
        errx("Bind error");
    // запускаем сервак  
    if (-1 == listen(sockfd, 25)) errx("Listen error");
    while (true) {                        // ждем данных от клиента
        char buff[BUFFSIZE + 1];           // буфер для отправки и получения данных
        cout << "Listening..." << endl;
        int connfd;                       // Подключенный сокет        
        if ((connfd = accept(sockfd, NULL, NULL)) < 0) errx("Accept error");
        rc = read(connfd, buff, BUFFSIZE);
        if (rc > 0) {
            cout << "Recv: " << buff << endl;
            rc = write(connfd, buff, strlen(buff) + 1);
            if (rc < 0) perror("write data failed");
        }
        else if (rc < 0) { perror( "read data failed" ); }
        else if (rc == 0) { cout << "client closed connection" << endl; };
        close(connfd);
    }
    return 0;
}
Вложения
socket_common.cc
(355 байт) 1 скачивание
socket_client.cc
(1.38 КБ) 1 скачивание
socket_serv.cc
(1.91 КБ) 1 скачивание

Аватара пользователя
Olej
Писатель
Сообщения: 16753
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Простейшая реализация клиент-серверного консольного приложения через сокеты на с++

Непрочитанное сообщение Olej » 19 сен 2022, 16:03

Olej писал(а):
19 сен 2022, 16:00
Переделал я ваш TCP клиент + сервер...
Вот как это выполняется:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/TCPIP-сервер/С++$ ./socket_client
Please input: 123
Recv: 123
Please input: 345
Recv: 345
Please input: 567
Recv: 567
Please input: 789
Recv: 789
Please input: ^C

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/TCPIP-сервер/С++$ ./socket_client
Please input: фыва
Recv: фыва
Please input: asdf
Recv: asdf
Please input: zxcv
Recv: zxcv
Please input: ^C
Клиент запускается дважды - обратите внимание. Сервер ретранслирует полученное:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/TCPIP-сервер/С++$ ./socket_serv
Listening...
Recv: 123
Listening...
Recv: 345
Listening...
Recv: 567
Listening...
Recv: 789
Listening...
client closed connection
Listening...
Recv: фыва
Listening...
Recv: asdf
Listening...
Recv: zxcv
Listening...
client closed connection
Listening...
^C
Server finished

Аватара пользователя
Olej
Писатель
Сообщения: 16753
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Простейшая реализация клиент-серверного консольного приложения через сокеты на с++

Непрочитанное сообщение Olej » 19 сен 2022, 16:19

Olej писал(а):
19 сен 2022, 16:00
Переделал я ваш TCP клиент + сервер...
Существенных изменений там к вашему коду немного, больше косметика ... принципиально только следующее:

1. По возможности, не используйте для TCP send(sockfd, ...) и recv(sockfd, ... ). А используйте write() и read(), которые используются и для любого символьного потока...

2. И связано это с тем (и это порождает множество ошибок), что в TCP нет никаких пакетов - TCP это поток, "труба", куда в один конец вдувается последовательность байт, а с другого сыпется последовательность байт ... и совершенно не обязательно число байт, которое засылается с одного конца, совпадает с тем, что будет считано единичной операцией чтения с приёмного конца. TCP - сложный механизм (в отличие от UDP), где работают "под капотом" сложные механизмы: алгоритм Нэйгла, медленный старт, динамическая настройка окон передачи-приёма, контроль целостности и повторы передачи, экспоненциальный рост периодов повторной передачи...
Вы можете, например, передавать последовательно каждым send() по 100 байт, а на приёмном конце принимать recv(), иногда, и 50 байт, и 200 байт :-o :-( В локальной сети это наблюдать можно очень редко, а вот через маршрутизаторы и в Интернет - запросто!
В TCP/IP нет "сообщений", сообщения в сетях TCP/IP должны быть понятием более высокого прикладного уровня.

3. Так что в некотором смысле и мой переделанный код не 100% корректный. По хорошему в поток TCP можно передавать "сообщения" только если:
а). фиксированной известной длины
б). самоопределённой длины ... например, передавая 1-м байтом длину следующего сообщения
в). заканчивая каждое сообщение договорным разделителем (окончанием) - так HTTP и многие другие Интернет прикладные протоколы заканчивает сообщение "\n\n" (пустой строкой).

Аватара пользователя
Olej
Писатель
Сообщения: 16753
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Простейшая реализация клиент-серверного консольного приложения через сокеты на с++

Непрочитанное сообщение Olej » 19 сен 2022, 17:15

Olej писал(а):
19 сен 2022, 16:19
заканчивая каждое сообщение договорным разделителем (окончанием) - так HTTP
В этом смысле интересная (для C++) идея - представить сокет (он же есть файловы дескриптор) как поток istream и ostream ... вот подсмотрел я (How to construct a c++ fstream from a POSIX file descriptor?) такой код:

Код: Выделить всё

#include <ext/stdio_filebuf.h>
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
    ofstream ofs("test.txt");
    ofs << "Writing to a basic_ofstream object..." << endl;
    ofs.close();

    int posix_handle = fileno(::fopen("test.txt", "r"));

    __gnu_cxx::stdio_filebuf<char> filebuf(posix_handle, std::ios::in); // 1
    istream is(&filebuf); // 2

    string line;
    getline(is, line);
    cout << "line: " << line << std::endl;
    return 0;
}
Вот он "в натуре":

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/TCPIP-сервер/С++$ c++ istream1.cc -o istream1

olej@R420:~/2022/own.BOOKs/TCPIP-сервер/С++$ ./istream1 
line: Writing to a basic_ofstream object...
И туда (потоки) писать и читать строки string, заканчивающиеся '\n' - тогда и читаться онри могут getline(is, line) - до разделителя.

Аватара пользователя
Olej
Писатель
Сообщения: 16753
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Простейшая реализация клиент-серверного консольного приложения через сокеты на с++

Непрочитанное сообщение Olej » 19 сен 2022, 21:00

Olej писал(а):
19 сен 2022, 17:15
И туда (потоки) писать и читать строки string, заканчивающиеся '\n'
Вот тогда будет корректно!
Делаю по образу и подобию...
В общий файл дописать 1 строчку:

Код: Выделить всё

#include <ext/stdio_filebuf.h>
(И оттуда... и отовсюду - можно повыбрасывать всё что связано с буфером buff и его длиной BUFFSIZE - теперь передаваемые сообщения могут быть какой-то немерянной длины ... я даже не помню число максимальной длины string - но там о-о-о-чень много. :-D И теперь сообщения можете передавать больше MTU сети, можете передавать тысячи байт - сам стек TCP/IP будет фрагментировать IP пакеты.)

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/TCPIP-сервер/С++$ cat stream_serv.cc 
#include <csignal>
#include "socket_common.cc"

int sockfd;                               // прослушивающий сокет

void stopServerRunning(int p) {
    close(sockfd);
    cout << endl << "Server finished" << endl;     
    exit(0);
}

int main() {
    if (-1 == (sockfd = socket(AF_INET, SOCK_STREAM, 0)))
        errx("Create socket error");
    signal(SIGINT, stopServerRunning);    // выключение сервера при вводе Ctrl + C
    int rc;
    if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &rc, sizeof(rc)) != 0)
        errx("Set socket option failed");
    struct sockaddr_in servaddr;          // структура TCP адреса
    bzero(&servaddr, sizeof(servaddr));   // инициализация адреса
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(DEFAULT_PORT);
    // подключаемся к порту
    if (-1 == bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)))
        errx("Bind error");
    // запускаем сервак  
    if (-1 == listen(sockfd, 25)) errx("Listen error");
    while (true) {                        // ждем данных от клиента
        cout << "Listening..." << endl;
        int connfd;                       // подключенный сокет        
        if ((connfd = accept(sockfd, NULL, NULL)) < 0) errx("Accept error");
        string msg;
        __gnu_cxx::stdio_filebuf<char> filebufi(connfd, std::ios::in);
        istream is(&filebufi);
        getline(is, msg);                 // чтение из сокета
        if (is.rdstate() == std::ios_base::goodbit) {
            cout << "считано из сокета:\t" << msg << endl;
            __gnu_cxx::stdio_filebuf<char> filebufo(connfd, std::ios::out);
            ostream os(&filebufo);
            os << msg + "\n" << flush;     // ретрансляция в сокет
            if (os.rdstate() == std::ios_base::goodbit)
                cout << "записано в сокет:\t" << msg << endl;
            else
                cout << "что-то непонятное с записью!" << endl;            
        }
        else
            cout << "что-то непонятное с чтением!" << endl;
        close(connfd);
    }
    return 0;
}

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/TCPIP-сервер/С++$ cat stream_client.cc 
#include "socket_common.cc"

int main() {
#define SERVER_IP "127.0.0.1"         // IP-адрес сервера
    while (true) {
        int sockfd;                  // TCP сокет для отправки данных
        if (-1 == (sockfd = socket(AF_INET, SOCK_STREAM, 0)))
            errx("Create socket error");
        struct sockaddr_in servaddr;
        bzero(&servaddr, sizeof(struct sockaddr_in));
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(DEFAULT_PORT);
        inet_aton(SERVER_IP, &servaddr.sin_addr);
        // коннектимся к серверу
        if (-1 == connect(sockfd, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in)))
            errx("Connect error");
        // далее простейшие манипуляции с отправкой и получением данных
        cout << "Please input: " << flush;
        string msg;
        getline(cin, msg);           // чтение с терминала  
        __gnu_cxx::stdio_filebuf<char> filebufo(sockfd, std::ios::out);
        ostream os(&filebufo);
        os << msg + "\n" << flush;    // отправка введенного в TCP сокет
        if (os.rdstate() == std::ios_base::goodbit)
            cout << "записано в сокет:\t" << msg << endl;
        else
            cout << "что-то непонятное с записью!" << endl;
        __gnu_cxx::stdio_filebuf<char> filebufi(sockfd, std::ios::in);
        istream is(&filebufi);         // чтение из сокета подтверждения
        getline(is, msg);
        if (is.rdstate() == std::ios_base::goodbit)
            cout << "считано из сокета:\t" << msg << endl;
        else
            cout << "что-то непонятное с чтением!" << endl;
        close(sockfd);
    }
    return 0;
}
Всё стало только компактнее! :-D
Вложения
stream_client.cc
(1.84 КБ) 1 скачивание
stream_serv.cc
(2.3 КБ) 1 скачивание

Аватара пользователя
Olej
Писатель
Сообщения: 16753
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Простейшая реализация клиент-серверного консольного приложения через сокеты на с++

Непрочитанное сообщение Olej » 19 сен 2022, 21:03

Olej писал(а):
19 сен 2022, 21:00
Всё стало только компактнее!
Теперь формат строк обмена: любая последовательность байт (в том числе и UNICODE UTF-8) заканчивающиеся переводом строки '\n' (это и будет признаком разделяющим "сообщения").

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/TCPIP-сервер/С++$ make
c++ -std=c++11 -O3 -Wall stream_client.cc -lpthread -o stream_client
c++ -std=c++11 -O3 -Wall stream_serv.cc -lpthread -o stream_serv
Работаем:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/TCPIP-сервер/С++$ ./stream_client
Please input: 1234
записано в сокет:       1234
считано из сокета:      1234
Please input: asdf
записано в сокет:       asdf
считано из сокета:      asdf
Please input: ^C

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/TCPIP-сервер/С++$ ./stream_client
Please input: ячсиясми
записано в сокет:       ячсиясми
считано из сокета:      ячсиясми
Please input: 987654321
записано в сокет:       987654321
считано из сокета:      987654321
Please input: ^C

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/TCPIP-сервер/С++$ ./stream_serv
Listening...
считано из сокета:      1234
записано в сокет:       1234
Listening...
считано из сокета:      asdf
записано в сокет:       asdf
Listening...
что-то непонятное с чтением!
Listening...
считано из сокета:      ячсиясми
записано в сокет:       ячсиясми
Listening...
считано из сокета:      987654321
записано в сокет:       987654321
Listening...
что-то непонятное с чтением!
Listening...
^C
Server finished

Аватара пользователя
Olej
Писатель
Сообщения: 16753
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Простейшая реализация клиент-серверного консольного приложения через сокеты на с++

Непрочитанное сообщение Olej » 20 сен 2022, 02:06

Olej писал(а):
19 сен 2022, 21:03
Теперь формат строк обмена: любая последовательность байт (в том числе и UNICODE UTF-8) заканчивающиеся переводом строки '\n' (это и будет признаком разделяющим "сообщения").
И, на сегодня последний вариант ... если предыдущий не очень понятный, потому что использует не документированный (или слабо документированный) вызов для __gnu_cxx::stdio_filebuf<char> ...
Тот же формат - строка заканчивающаяся '\n' (или здесь можно сделать чем угодно - getdelim()). В общий файл socket_common.cc добавлю ещё одну строку:

Код: Выделить всё

#include <fcntl.h>
Клиент:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/TCPIP-сервер/С++$ cat fstream_client.cc 
#include "socket_common.cc"

int main() {
#define SERVER_IP "127.0.0.1"         // IP-адрес сервера
    while (true) {
        int sockfd;                  // TCP сокет для отправки данных
        if (-1 == (sockfd = socket(AF_INET, SOCK_STREAM, 0)))
            errx("Create socket error");
        struct sockaddr_in servaddr;
        bzero(&servaddr, sizeof(struct sockaddr_in));
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(DEFAULT_PORT);
        inet_aton(SERVER_IP, &servaddr.sin_addr);
        // коннектимся к серверу
        if (-1 == connect(sockfd, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in)))
            errx("Connect error");
        // далее простейшие манипуляции с отправкой и получением данных
        cout << "Please input: " << flush;
        string msg;
        getline(cin, msg);           // чтение с терминала  
        FILE* fo = ::fdopen(sockfd, "w");
        ssize_t size = ::fputs((msg + "\n").c_str(), fo);
        ::fflush(fo);
        if (size > 0)
            cout << "записано в сокет:\t" << msg << endl;
        else
            cout << "что-то непонятное с записью!" << endl;
        FILE* fi = ::fdopen(sockfd, "r"); 
        char *line = NULL;
        size_t len = 0;
        if (::getline(&line, &len, fi) > 0)
            cout << "считано из сокета:\t" << line;
        else
            cout << "что-то непонятное с чтением!" << endl;
        free(line);
        close(sockfd);
    }
    return 0;
}
Сервер:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/TCPIP-сервер/С++$ cat fstream_serv.cc 
#include <csignal>
#include "socket_common.cc"

int sockfd;                               // прослушивающий сокет

void stopServerRunning(int p) {
    close(sockfd);
    cout << endl << "Server finished" << endl;     
    exit(0);
}

int main() {
    if (-1 == (sockfd = socket(AF_INET, SOCK_STREAM, 0)))
        errx("Create socket error");
    signal(SIGINT, stopServerRunning);    // выключение сервера при вводе Ctrl + C
    int rc;
    if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &rc, sizeof(rc)) != 0)
        errx("Set socket option failed");
    struct sockaddr_in servaddr;          // структура TCP адреса
    bzero(&servaddr, sizeof(servaddr));   // инициализация адреса
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(DEFAULT_PORT);
    // подключаемся к порту
    if (-1 == bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)))
        errx("Bind error");
    // запускаем сервак  
    if (-1 == listen(sockfd, 25)) errx("Listen error");
    while (true) {                        // ждем данных от клиента
        cout << "Listening..." << endl;
        int connfd;                       // подключенный сокет        
        if ((connfd = accept(sockfd, NULL, NULL)) < 0) errx("Accept error");
        FILE* fi = ::fdopen(connfd, "r"); 
        char *line = NULL;
        size_t len = 0;
        if (::getline(&line, &len, fi) > 0) {
            cout << "считано из сокета:\t" << line;
            FILE* fo = ::fdopen(connfd, "w");
            ssize_t size = ::fputs(line, fo);
            ::fflush(fo);
            if (size > 0)
                cout << "записано в сокет:\t" << line;
            else
                cout << "что-то непонятное с записью!" << endl;
            free(line);
        }
        else
            cout << "что-то непонятное с чтением!" << endl;
        close(connfd);
    }
    return 0;
}
Вложения
fstream_client.cc
(1.64 КБ) 1 скачивание
fstream_serv.cc
(2.16 КБ) 1 скачивание

Аватара пользователя
Olej
Писатель
Сообщения: 16753
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Простейшая реализация клиент-серверного консольного приложения через сокеты на с++

Непрочитанное сообщение Olej » 20 сен 2022, 02:11

Olej писал(а):
20 сен 2022, 02:06
И, на сегодня последний вариант

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/TCPIP-сервер/С++$ make
...
c++ -std=c++11 -O3 -Wall fstream_client.cc -lpthread -o fstream_client
c++ -std=c++11 -O3 -Wall fstream_serv.cc -lpthread -o fstream_serv
Выполнение:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/TCPIP-сервер/С++$ ./fstream_client
Please input: 1242511
записано в сокет:	1242511
считано из сокета:	1242511
Please input: adgadgadfg
записано в сокет:	adgadgadfg
считано из сокета:	adgadgadfg
Please input: ^C

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/TCPIP-сервер/С++$ ./fstream_client
Please input: дордларолар
записано в сокет:	дордларолар
считано из сокета:	дордларолар
Please input: 0ву0а0п0
записано в сокет:	0ву0а0п0
считано из сокета:	0ву0а0п0
Please input: ^C

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/TCPIP-сервер/С++$ ./fstream_serv
Listening...
считано из сокета:	1242511
записано в сокет:	1242511
Listening...
считано из сокета:	adgadgadfg
записано в сокет:	adgadgadfg
Listening...
что-то непонятное с чтением!
Listening...
считано из сокета:	дордларолар
записано в сокет:	дордларолар
Listening...
считано из сокета:	0ву0а0п0
записано в сокет:	0ву0а0п0
Listening...
что-то непонятное с чтением!
Listening...
^C
Server finished

Ответить

Вернуться в «Программирование»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя