С Новым годом! Форум программистов, компьютерный форум, киберфорум
Boost C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
2 / 2 / 0
Регистрация: 07.04.2016
Сообщений: 298

Асинхронный сервер\клиент

28.06.2025, 23:31. Показов 4467. Ответов 14

Студворк — интернет-сервис помощи студентам
Здравствуйте.

В общем разбился об стену под названием асинхронный сервер\клиент, требуется помощь.

Имеем:
1. Win 10 x64;
2. Boost 1.88;
3. Компилятор msys2 mingw64;

Что непонятно:
Не понимаю как создать сервер и как создать сессию. Как связывать\привязывать\перевязывать\завяз ывать\распутывать\передавать\отдавать\от нимать "io_context" и сокеты(актив и пассив). В каких-то статьях(и в неактуальном по версии библиотеки учебнике тоже) используют "acceptor.bind (...)", где-то сразу в конструкторе инициализируют, естественно без толкового описания. Добавим сюда(в "объясняющие" статьи) факт использования лямбда-функций совместно с максимально укороченным кодом в ущерб понятности, которые не делают код более простым для понимания.

Не по теме:


Когда я вижу статью "объяснятора" с лямбда-функцией, то сразу хочется попросить его переписать через обычную функцию, посмотреть, что и как он будет передавать. Если в большинстве лямбд всё ясно, то вот с boost::asio нет. Правда на момент "сейчас" уже есть понимание, я так думаю.



Что делал:
1. То же, что тут(Boost::asio - ошибка использования сокета) и где-то еще задавал вопросы, связанные с этой темой;
2. Оставил код, который хотя бы компилируется но сама прога не рабочая. Код прикреплю ниже.

Какая нужна помощь:
Наверное, это нагло будет, но всё же:
Нужен готовый код в котором:
1. используется boost c++(укажите версию, т.к. чать методов и переменных не актуальны от версии к версии);
2. для windows;
3. лямбды заменены на "std::bind ()"(потому, что мне проще понять через такой способ);
4. без "сложных" сжатооднострочных выражений, в которых создаётся объек, сразу вызывается метод с передачей и это всё применяется в каком-нибудь "std::move" для какого-то другого объекта, который есть "общий" указатель в векторе, который входит в матрицу указателей и т.д.;
5. Отдельно класс "сервер" и класс "сессия", допустим, сейчас у меня один клиент, а потом может быть 100500+;
6. В общем максимально просто для такого как я: тупенького начинающего.

Код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <iostream>
#include <memory> // Для std::shared_ptr
#include <boost/asio.hpp>
#include <boost/system/error_code.hpp>
 
#include <thread>
 
 
class Session {
    public:
 
    public:
        Session () {}
 
    public:
};
 
 
 
 
 
 
class Server {
    public:
        boost::asio::ip::tcp::endpoint m_endpoint;
        boost::asio::io_context m_ioContext;
        boost::asio::ip::tcp::acceptor m_acceptor;
 
    public:
        Server (boost::asio::ip::address_v4 aIpAddressV4, unsigned short aPort)
                : m_endpoint (aIpAddressV4, aPort),
                    m_acceptor (m_ioContext, m_endpoint.protocol() ) {
        }
 
        ~Server () {
/* Был необходим для понимания когда и в каких
случаюях этот объект успевал "умереть" пока
выполнялись асинхронные операции. */
std::cout << "thread [" << std::this_thread::get_id() << "]:: ";
std::cout << "~Server" << std::endl;
        }
 
    public:
        void processTheConnection (std::shared_ptr <Server> aSharedPtrToServer,
                                    const boost::system::error_code& aErrorCode) {
 
            if (aErrorCode.value() != 0) {
                // ...
            }
            else {
                // ...
            }
 
            // Продолжаем принимать новые запросы на соединение.
            this->startAccept ();
        }
 
 
 
 
        void startAccept() {
            m_acceptor.listen();
 
            std::shared_ptr <Server> sharedPtrToThisObject (this); // Нужен для продления "жизни" этого объекта.
            boost::system::error_code errorCode1;
            auto bindedProcessTheConnection = std::bind (&Server::processTheConnection, this,
                                            sharedPtrToThisObject,
                                            errorCode1);
 
            m_acceptor.async_accept (/* так и не определился что сюда передавать, ведь есть 8 вариантов перегрузок */);
 
            m_ioContext.run();
        }
};
 
 
 
 
 
 
 
int main() {
    SetConsoleCP (1251);
    SetConsoleOutputCP (1251);
 
    boost::asio::ip::address_v4 ipAddressV4;
    unsigned short port = 3333;
 
    try {
        Server Server1 (ipAddressV4, port);
        Server1.startAccept ();
    }
    catch (std::exception& e) {
std::cerr << "main:: Исключение: " << e.what() << std::endl;
    }
 
 
    system ("pause");
    return 0;
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
28.06.2025, 23:31
Ответы с готовыми решениями:

Клиент-Сервер (асинхронный): некоррено передаётся файл
Добрый день! Пишу клиент и сервер с передачей текстового файла от клиента серверу. Задачу нужно...

Асинхронный сервер и клиент Boost Asio
Здравствуйте. Попробовал написать нечто такое. Но на этом этапе чтения не происходит ничего. Дальше...

Клиент/сервер - Клиент/сервер
Доброго времени суток, Ув. Форумчане. Необходимо написать TCP чат, да не простой чат, а который...

14
 Аватар для andrey_f
883 / 536 / 228
Регистрация: 21.02.2011
Сообщений: 5,706
01.07.2025, 12:24
пример попроще
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <iostream>
#include <memory>
#include <boost/asio.hpp>
#include <thread>
 
using boost::asio::ip::tcp;
 
// Класс сессии — управляет одним соединением
class Session : public std::enable_shared_from_this<Session> {
public:
    explicit Session(tcp::socket socket)
        : socket_(std::move(socket)) {}
 
    void start() {
        do_read();
    }
 
private:
    tcp::socket socket_;
    enum { max_length = 1024 };
    char data_[max_length];
 
    void do_read() {
        auto self(shared_from_this());
        socket_.async_read_some(
            boost::asio::buffer(data_, max_length),
            [this, self](boost::system::error_code ec, std::size_t length) {
                if (!ec) {
                    // Просто выводим полученные данные
                    std::cout << "Received: " << std::string(data_, length) << std::endl;
                    do_read(); // читаем дальше
                }
            });
    }
};
 
// Класс сервера — принимает соединения
class Server {
public:
    Server(boost::asio::io_context& io_context, const tcp::endpoint& endpoint)
        : acceptor_(io_context, endpoint) {
        start_accept();
    }
 
private:
    tcp::acceptor acceptor_;
 
    void start_accept() {
        // Создаём сокет для нового клиента
        auto socket = std::make_shared<tcp::socket>(acceptor_.get_executor().context());
 
        // Передаём обработчик через std::bind
        acceptor_.async_accept(
            *socket,
            std::bind(&Server::handle_accept, this,
                      socket,
                      std::placeholders::_1));
    }
 
    void handle_accept(std::shared_ptr<tcp::socket> socket,
                       const boost::system::error_code& ec) {
        if (!ec) {
            // Создаём новую сессию для клиента
            auto session = std::make_shared<Session>(std::move(*socket));
            session->start();
        }
        // Ждём следующего клиента
        start_accept();
    }
};
 
int main() {
    try {
        boost::asio::io_context io_context;
 
        // Указываем IP и порт (например 127.0.0.1:3333)
        tcp::endpoint endpoint(boost::asio::ip::make_address("127.0.0.1"), 3333);
 
        Server server(io_context, endpoint);
 
        // Запускаем цикл обработки событий
        io_context.run();
    } catch (std::exception& e) {
        std::cerr << "Exception: " << e.what() << "\n";
    }
 
    return 0;
}
1
2 / 2 / 0
Регистрация: 07.04.2016
Сообщений: 298
10.07.2025, 22:05  [ТС]
можешь объяснить чем отличается мой код от твоего изза чего мой код не работает, а твой работает. Я не пойму.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
class Session : public std::enable_shared_from_this <Session> {
    public:
        boost::asio::ip::tcp::socket m_socket;
        unsigned int m_sizeMessages = 1024;
        char m_cString [1024];
 
    public:
        explicit Session (boost::asio::ip::tcp::socket aSocket)
                    : m_socket (std::move (aSocket) ) {}
 
        ~Session () {
            std::cout << "~Session" << std::endl;
        }
 
    public:
        void processTheClientMessage (std::shared_ptr <Session> aSharedPtrToSession,
                                    Session* aSessionObject,
                                    const boost::system::error_code& aErrorCode) {
 
            if (aErrorCode.value() != 0) {
                // ...
            }
            else {
                std::cout << "client message = " << std::string(m_cString, m_sizeMessages) << std::endl;
            }
 
            this->readFromSocket();
        }
 
        void readFromSocket () {
            std::shared_ptr <Session> sharedPtrToThisObject (this);
            boost::system::error_code errorCode1;
            auto bindedProcessTheClientMessage = std::bind (&Session::processTheClientMessage,
                                            this,
                                            sharedPtrToThisObject,
                                            this,
                                            errorCode1);
 
            m_socket.async_read_some (boost::asio::buffer (m_cString, m_sizeMessages),
                                                    bindedProcessTheClientMessage);
        }
};
 
 
 
 
 
 
class Server {
    public:
        boost::asio::ip::tcp::endpoint m_endpoint;
        boost::asio::ip::tcp::acceptor m_acceptor;
        std::vector <Session*> m_Sessions;
        int m_sessionCounter;
 
    public:
        Server (boost::asio::io_context& aIoContext,
                    boost::asio::ip::address_v4 aIpAddressV4,
                    unsigned short aPort)
                : m_endpoint (aIpAddressV4, aPort),
                m_acceptor (aIoContext, m_endpoint) {
            // ...
            m_sessionCounter = 0;
        }
 
        ~Server () {
            std::cout << "~Server" << std::endl;
        }
 
    public:
        void processTheConnection (std::shared_ptr <Server> aSharedPtrToServer,
                                    std::shared_ptr <boost::asio::ip::tcp::socket> aSharedPtrSocket,
                                    const boost::system::error_code& aErrorCode) {
 
            if (aErrorCode.value() != 0) {
                // ...
            }
            else {
                m_Sessions.push_back (new Session (std::move (*aSharedPtrSocket)) );
                m_Sessions [m_sessionCounter] ->readFromSocket();
                ++m_sessionCounter;
            }
 
            this->startAccept ();
        }
 
 
 
 
        void startAccept() {
            std::shared_ptr <boost::asio::ip::tcp::socket> sharedPtrSocket1 (new boost::asio::ip::tcp::socket (m_acceptor.get_executor()) ); // Видимо, возвращает "io_context".
            std::shared_ptr <Server> sharedPtrToThisObject (this);
            boost::system::error_code errorCode1;
            auto bindedProcessTheConnection = std::bind (&Server::processTheConnection, this,
                                            sharedPtrToThisObject,
                                            sharedPtrSocket1,
                                            errorCode1);
 
            m_acceptor.async_accept (*sharedPtrSocket1, bindedProcessTheConnection);
        }
};
 
 
 
 
 
 
 
int main() {
    boost::asio::ip::address_v4 ipAddressV4;
    unsigned short port = 3333;
 
        try {
            boost::asio::io_context ioContext1;
 
            Server Server1 (ioContext1, ipAddressV4, port);
            Server1.startAccept (); // Начать принимать новые соединения.
 
            ioContext1.run();
        }
        catch (std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
        }
 
    system ("pause");
    return 0;
}
0
Заблокирован
11.07.2025, 03:26
Цитата Сообщение от Palich Посмотреть сообщение
std::shared_ptr <Session> sharedPtrToThisObject (this);
Как минимум ошибка тут.
Цитата Сообщение от Palich Посмотреть сообщение
std::enable_shared_from_this
Призван именно для корректного создания shared_ptr from this.
Посредством вызова shared_from_this()

Добавлено через 26 минут
Цитата Сообщение от Palich Посмотреть сообщение
std::vector <Session*> m_Sessions;
Плюс, почему вектор указателей а не shared_ptr ???
Зачем тогда были нужны все эти манипуляции с std::enable_shared_from_this ?
1
2 / 2 / 0
Регистрация: 07.04.2016
Сообщений: 298
11.07.2025, 18:48  [ТС]
Исправил по твоим комментариям, всё равно не работает )

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <iostream>
#include <string>
#include <vector>
#include <memory> // Для std::shared_ptr
#include <array> // Для std::array
#include <boost/asio.hpp>
#include <boost/system/error_code.hpp>
 
#include <thread>
 
 
class Session : public std::enable_shared_from_this <Session> {
    public:
        boost::asio::ip::tcp::socket m_socket;
        unsigned int m_sizeMessages = 1024;
        char m_cString [1024];
 
    public:
        explicit Session (boost::asio::ip::tcp::socket aSocket)
                    : m_socket (std::move (aSocket) ) {}
 
        ~Session () {
            std::cout << "~Session" << std::endl;
        }
 
    public:
        void processTheClientMessage (std::shared_ptr <Session> aSharedPtrToSession,
                                    Session* aSessionObject,
                                    const boost::system::error_code& aErrorCode) {
 
            if (aErrorCode.value() != 0) {
                // ...
            }
            else {
std::cout << "client message = " << std::string (m_cString, m_sizeMessages) << std::endl;
            }
 
            this->readFromSocket();
        }
 
        void readFromSocket () {
            auto self (shared_from_this());
            boost::system::error_code errorCode1;
            auto bindedProcessTheClientMessage = std::bind (&Session::processTheClientMessage,
                                            this,
                                            self,
                                            this,
                                            errorCode1);
 
            m_socket.async_read_some (boost::asio::buffer (m_cString, m_sizeMessages),
                                                    bindedProcessTheClientMessage);
        }
};
 
 
 
 
 
 
class Server {
    public:
        boost::asio::ip::tcp::endpoint m_endpoint;
        boost::asio::ip::tcp::acceptor m_acceptor;
        std::vector <std::shared_ptr <Session>> m_sharedPtrSessions;
        int m_sessionCounter;
 
    public:
        Server (boost::asio::io_context& aIoContext,
                    boost::asio::ip::address_v4 aIpAddressV4,
                    unsigned short aPort)
                : m_endpoint (aIpAddressV4, aPort),
                m_acceptor (aIoContext, m_endpoint) {
            // ...
            m_sessionCounter = 0;
        }
 
        ~Server () {
std::cout << "~Server" << std::endl;
        }
 
    public:
        void processTheConnection (std::shared_ptr <Server> aSharedPtrToServer,
                                    std::shared_ptr <boost::asio::ip::tcp::socket> aSharedPtrSocket,
                                    const boost::system::error_code& aErrorCode) {
 
            if (aErrorCode.value() != 0) {
                // ...
            }
            else {
                m_sharedPtrSessions.push_back (std::make_shared <Session> (std::move (*aSharedPtrSocket)) );
                m_sharedPtrSessions [m_sessionCounter] ->readFromSocket();
                ++m_sessionCounter;
            }
 
            this->startAccept ();
        }
 
 
 
 
        void startAccept() {
            std::shared_ptr <boost::asio::ip::tcp::socket> sharedPtrSocket1 (new boost::asio::ip::tcp::socket (m_acceptor.get_executor()) ); // Видимо, возвращает "io_context".
            std::shared_ptr <Server> sharedPtrToThisObject (this);
            boost::system::error_code errorCode1;
            auto bindedProcessTheConnection = std::bind (&Server::processTheConnection, this,
                                            sharedPtrToThisObject,
                                            sharedPtrSocket1,
                                            errorCode1);
 
            m_acceptor.async_accept (*sharedPtrSocket1, bindedProcessTheConnection);
        }
};
 
 
 
 
 
 
 
int main() {
    boost::asio::ip::address_v4 ipAddressV4;
    unsigned short port = 3333;
 
        try {
            boost::asio::io_context ioContext1;
 
            Server Server1 (ioContext1, ipAddressV4, port);
            Server1.startAccept (); // Начать принимать новые соединения.
 
            ioContext1.run();
        }
        catch (std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
        }
 
    system ("pause");
    return 0;
}
Добавлено через 2 минуты
Цитата Сообщение от SmallEvil Посмотреть сообщение
Плюс, почему вектор указателей а не shared_ptr ???
потому, что нет понимания изза неработающего кода выше.

Добавлено через 5 минут
прочитал не одну статью про "shared_ptr" но для полного понимания нужна практика, её у меня нет, единственное где оно потребовалось это тут, но тут код не работает.
0
Заблокирован
11.07.2025, 22:10
Цитата Сообщение от Palich Посмотреть сообщение
std::shared_ptr <Server> sharedPtrToThisObject (this);
Ещё тут, навскидку.

А вообще, вам бы потренироваться с умными указателями на более простых примерах.
Что бы избежать одновременных ошибок и от работы с boost-ом и стандартными умными указателями.

Добавлено через 1 минуту
Я вот почти не работал с boost.
Поэтому могу смотреть только с одной стороны.
0
2 / 2 / 0
Регистрация: 07.04.2016
Сообщений: 298
18.08.2025, 12:22  [ТС]
в общем так и не понял как написать клиент-сервер
0
Заблокирован
18.08.2025, 13:12
Цитата Сообщение от Palich Посмотреть сообщение
в общем так и не понял как написать клиент-сервер
Например, походу не очень старое : boost-tcp-server-client [github]
0
2 / 2 / 0
Регистрация: 07.04.2016
Сообщений: 298
19.08.2025, 10:26  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
: boost-tcp-server-client [github]
не открывается, с впн тоже не открывается, если открыть код страницы, то перейдя по ссылке(которую таковой сложно назвать) пишет "запрош. страна не существует".

по поводу предыдущих ссылок:

I. эта: https://www.codingwiththomas.c... nt-example
все те же самые вопросы:
1. почему используют лямбду функцию, а не std::bind, потому что в оф. документации указан "токен" ?
2. каким образом в методе "void do_accept()" у класса сервера в этой чудо лямбде инициализируется "socket" ?
3. в методе "void wait_for_request()" у класса сессии в чудо лямбде захватывается 2 объекта: "shared_from_this()" и непосредственно сам объект "this", тогда вопрос: зачем захватывать "this" если и так захватывается "shared_from_this()" ? для доступа к своим членам ? разве через "shared_from_this()" это нельзя сделать ?

II. была ссылка на гит:
1. вопрос такой же как и вопрос 1 выше.
0
Заблокирован
19.08.2025, 11:41
Цитата Сообщение от Palich Посмотреть сообщение
не открывается
Сломалось : https://github.com/alejandrofsevilla/boost-tcp-server-client

Добавлено через 1 минуту
Цитата Сообщение от Palich Посмотреть сообщение
1. почему используют лямбду функцию
Может потому что это естественно? Тут я очень сильно затрудняюсь ответить, так как не понимаю вопроса.

Добавлено через 15 минут
Цитата Сообщение от Palich Посмотреть сообщение
2. каким образом в методе "void do_accept()" у класса сервера в этой чудо лямбде инициализируется "socket" ?
Нужно грызть tcp::acceptor.
Вот там использовали async_accept acceptor-а.
Идем и смотрим что это и для чего.

Ну вот вы нашли эту перегрузку.
И копаете дальше и дальше. Пока весь буст не будет понятен )

Вот пример на фнкции, как вы и хотели, на том же справке из офф. буста.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void accept_handler(const boost::system::error_code& error,
    boost::asio::ip::tcp::socket peer)
{
  if (!error)
  {
    // Accept succeeded.
  }
}
 
...
 
boost::asio::ip::tcp::acceptor acceptor(my_context);
...
acceptor.async_accept(accept_handler);
Да это не легкое, изучать буст.

Добавлено через 11 минут
Цитата Сообщение от Palich Посмотреть сообщение
в этой чудо лямбде инициализируется "socket" ?
Ну так он передается.
А как у вас он инициализируется?
Вероятно он приходит уже готовый. Этим занимается внутренняя реализация acceptor.
Не то что бы я прям горю желанием сейчас во всём этом разбираться.
Но лучше документации чем из офф. буста, найти будет затруднительно.
0
2 / 2 / 0
Регистрация: 07.04.2016
Сообщений: 298
19.08.2025, 12:24  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
Может потому что это естественно?
когда-то давно читал, что лямбду лучше использовать для коротких функций типа а+б, тут же нужно обработать код ошибки, потом если нужно, что-то сделать(передать в друг. функцию или тут же обработать) с сообщением. Т.е. это не простая функция уже. А если её заменить на std::bind, то вот как быть с soket'ом, который инициализируется acceptor'ом я не понял. На данный момент нашел другой способ, и вроде бы близок к рабочему коду, но не с помощью лямбды ) Я не против её, но когда её тыкают везде.... ну такое себе, конкретно в сетевом программир. конкретно в бусте у меня от лямбды ж.... подгорать начала.

Цитата Сообщение от SmallEvil Посмотреть сообщение
Ну вот вы нашли эту перегрузку.
я её видел ) но не понимал что с ней делать т.к. описание непонятное.

Цитата Сообщение от SmallEvil Посмотреть сообщение
Вероятно он приходит уже готовый. Этим занимается внутренняя реализация acceptor.
теперь чуть стало легче с пониманием этой перегрузки )
0
Заблокирован
19.08.2025, 14:41
Цитата Сообщение от Palich Посмотреть сообщение
Я не против её, но когда её тыкают везде.... ну такое себе, конкретно в сетевом программир. конкретно в бусте у меня от лямбды ж.... подгорать начала.
Потому что для примера этого достаточно, и лямбду быстренько раз два и состряпал "на месте".
Особенно если это относится к реализации именно этого метода, тогда даже плохо её выносить куда то.

Цитата Сообщение от Palich Посмотреть сообщение
огда-то давно читал, что лямбду лучше использовать для коротких функций типа а+б
Первый раз такое слышу.
0
2 / 2 / 0
Регистрация: 07.04.2016
Сообщений: 298
21.08.2025, 12:27  [ТС]
Как говорится "если долго мучиться, то что-нибудь получится".

В итоге у меня получился рабочий(т.е. программа запускается) код простого сервера и самое интересное, для меня, без "enable_shared_from_this<>" / "make_shared<>" / "shared_ptr<>" и чудо лямбдофункций.

В этом коде не реализовано отслеживание сессий.

Из того, что у меня получилось я вижу то, что:
1. "enable_shared_from_this<>" / "make_shared<>" / "shared_ptr<>" не нужно если указатель на объект где-то хранится и еще используется, в коде он хранится в векторе у сервера.
2. можно обойтись без лямбдофункций.

код:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include <iostream>
#include <string>
#include <vector>
#include <memory> // Для std::shared_ptr
#include <array> // Для std::array
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/system/error_code.hpp>
 
#include <thread>
 
 
class Session {
    public:
        boost::asio::ip::tcp::socket m_socket;
        char m_cString [256];
 
    public:
        Session (boost::asio::ip::tcp::socket aSocket)
                    : m_socket (std::move (aSocket) ) {
        }
 
        ~Session () {
            std::cout << "~Session" << std::endl;
        }
 
    public:
        boost::asio::ip::tcp::socket& getSocket () {
            return m_socket;
        }
 
 
 
        void processTheClientMessage (const boost::system::error_code& aErrorCode) {
 
            if (aErrorCode.value() != 0) {
 
                if (aErrorCode.value() == boost::asio::error::eof) {
                    this->closeTheSession();
                }
                else {
                    std::cout << aErrorCode.message() << std::endl;
                    this->closeTheSession();
                }
            }
            else {
                std::string string2 (m_cString);
                std::cout << "client message = " << string2 << std::endl;
                this->readFromSocket();
            }
        }
 
 
 
        void readFromSocket () {
            auto bindedProcessTheClientMessage = std::bind (&Session::processTheClientMessage,
                                            this,
                                            boost::asio::placeholders::error);
 
            m_socket.async_read_some (boost::asio::buffer (m_cString, 256),
                                                bindedProcessTheClientMessage);
        }
 
 
        void closeTheSession () {
            m_socket.shutdown (boost::asio::ip::tcp::socket::shutdown_both);
            m_socket.cancel ();
            m_socket.close ();
 
            this->~Session();
        }
};
 
 
 
 
 
 
class Server {
    public:
        boost::asio::ip::tcp::endpoint m_endpoint;
        boost::asio::ip::tcp::acceptor m_acceptor;
        std::vector <Session*> m_Sessions;
        int m_sessionCounter;
 
    public:
        Server (boost::asio::io_context& aIoContext,
                        boost::asio::ip::address_v4 aIpAddressV4,
                        unsigned short aPort)
                : m_endpoint (aIpAddressV4, aPort), m_acceptor (aIoContext, m_endpoint) {
            m_sessionCounter = 0;
        }
 
        ~Server () {
            std::cout << "~Server" << std::endl;
        }
 
    public:
        void processTheConnection (const boost::system::error_code& aErrorCode) {
 
            if (aErrorCode.value() != 0) {
            }
            else {
                m_Sessions [m_sessionCounter] ->readFromSocket();
                ++m_sessionCounter;
            }
 
            this->startAccept ();
        }
 
 
 
 
        void startAccept() {
            boost::asio::ip::tcp::socket socket1 (m_acceptor.get_executor() );
            m_Sessions.push_back (new Session (std::move (socket1)) );
 
            auto bindedProcessTheConnection = std::bind (&Server::processTheConnection,
                                            this,
                                            boost::asio::placeholders::error);
            m_acceptor.async_accept (m_Sessions [m_sessionCounter]->getSocket (),
                                                bindedProcessTheConnection);
        }
};
 
 
 
 
 
 
 
int main() {
    SetConsoleCP (1251);
    SetConsoleOutputCP (1251);
 
    std::string ipString = "127.0.0.1";
    boost::asio::ip::address_v4 ipAddressV4;
    unsigned short port = 3333;
 
    try {
        std::cout << std::endl;
        std::cout << "------ server --- ";
        std::cout << ipString << ":" << std::to_string (port);
        std::cout << " ------" << std::endl;
        std::cout << std::endl;
 
        boost::asio::io_context ioContext1;
        Server Server1 (ioContext1, ipAddressV4, port);
        Server1.startAccept ();
        ioContext1.run();
    }
    catch (std::exception& e) {
        std::cerr << "Exception: " << e.what() << std::endl;
    }
 
    system ("pause");
    return 0;
}




Не по теме:

была мысль весь код "закатать" в бесконечную лямбдофункцию, что бы у людей, их любящих, вытекли глаза :)

0
Заблокирован
21.08.2025, 13:15
Цитата Сообщение от Palich Посмотреть сообщение
В итоге у меня получился рабочий(т.е. программа запускается) код простого сервера
Работоспособность сервера проверяется немного не так.
Нужно убедится что связь клиент-сервер устанавливается и данные, в полном объеме, передаются и получаются участниками.

Не по теме:

Цитата Сообщение от Palich Посмотреть сообщение
была мысль весь код "закатать" в бесконечную лямбдофункцию, что бы у людей, их любящих, вытекли глаза :)
Лямбдофобия - это что то новенькое)

0
2 / 2 / 0
Регистрация: 07.04.2016
Сообщений: 298
23.08.2025, 22:59  [ТС]
И простой клиент тоже заработал. Так же без лямбдофункций и shared'подобных функций.

Цитата Сообщение от Palich Посмотреть сообщение
Из того, что у меня получилось я вижу то, что:
1. "enable_shared_from_this<>" / "make_shared<>" / "shared_ptr<>" не нужно если указатель на объект где-то хранится и еще используется, в коде он хранится в векторе у сервера.
2. можно обойтись без лямбдофункций.
Правда тут используется обычный указатель........

код клиента:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <array>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/system/error_code.hpp>
 
 
class Session {
    public:
        boost::asio::ip::tcp::endpoint m_endpoint;
        boost::asio::ip::tcp::socket m_socket;
        char m_cString [256];
 
    public:
        Session (boost::asio::ip::tcp::endpoint aEndpoint,
                        boost::asio::io_context& aContext)
                : m_endpoint (std::move (aEndpoint) ),
                    m_socket (aContext, m_endpoint.protocol() ) {
        }
 
        ~Session () {
            std::cout << "~Session" << std::endl;
            m_socket.cancel ();
            m_socket.close ();
        }
 
    public:
        void processConnection (const boost::system::error_code& aErrorCode) {
 
            if (aErrorCode.value() != 0) {
                std::cout << "Session::processConnection:: "
                        << "error read to the socket: error code = " << aErrorCode.value()
                        << ", message = " << aErrorCode.message() << std::endl;
 
                throw "connection error";
            }
        }
 
 
 
 
        void connectToServer () {
            auto bindedProcessConnection = std::bind (&Session::processConnection,
                                            this,
                                            boost::asio::placeholders::error);
 
            m_socket.async_connect (m_endpoint, bindedProcessConnection);
        }
 
 
 
 
        boost::asio::ip::tcp::socket& getSocket () {
            return m_socket;
        }
 
 
 
        void processTheServerMessage (const boost::system::error_code& aErrorCode) {
 
            if (aErrorCode.value() != 0) {
 
                if (aErrorCode.value() == boost::asio::error::eof) {
                    this->closeTheSession();
                }
                else {
                    std::cout << "Session::processTheServerMessage:: "
                                << "error read to the socket: error code = " << aErrorCode.value()
                                << ", message = " << aErrorCode.message() << std::endl;
                    this->closeTheSession();
                }
            }
            else {
                std::string string2 (m_cString);
                std::cout << "Session::processTheServerMessage:: server message = "
                                << string2 << std::endl;
                this->readFromSocket();
            }
        }
 
 
 
        void readFromSocket () {
 
            auto bindedprocessTheServerMessage = std::bind (&Session::processTheServerMessage,
                                            this,
                                            boost::asio::placeholders::error);
 
            m_socket.async_read_some (boost::asio::buffer (m_cString, 256),
                                                bindedprocessTheServerMessage);
        }
 
 
 
 
        void processWriteToSocket (const boost::system::error_code& aErrorCode) {
 
            if (aErrorCode.value() != 0) {
 
                if (aErrorCode.value() == boost::asio::error::eof) {
                    this->closeTheSession();
                }
                else {
                    std::cout << "Session::processWriteToSocket:: "
                        << "error read to the socket: error code = " << aErrorCode.value()
                        << ", message = " << aErrorCode.message() << std::endl;
                    this->closeTheSession();
                }
            }
        }
 
 
 
 
        void writeToSocket () {
            std::string string1 = "hello, i am client";
 
            auto bindedProcessWriteToSocket = std::bind (&Session::processWriteToSocket,
                                            this,
                                            boost::asio::placeholders::error);
            m_socket.async_write_some (boost::asio::buffer (string1),
                                                        bindedProcessWriteToSocket);
        }
 
 
 
 
        void closeTheSession () {
            this->~Session();
        }
};
 
 
 
 
 
 
int main() {
    SetConsoleCP (1251);
    SetConsoleOutputCP (1251);
 
    std::string ipString = "127.0.0.1";
    unsigned short port = 3333;
 
    std::cout << "------ client --- ";
    std::cout << ipString << ":" << std::to_string (port);
    std::cout << " ------" << std::endl;
    std::cout << std::endl;
 
    boost::system::error_code errorCode1;
    boost::asio::ip::address ipAddress = boost::asio::ip::make_address (ipString, errorCode1);
 
    if (errorCode1.value() == 0) {
        boost::asio::ip::tcp::endpoint endpoint1 (ipAddress, port);
        boost::asio::io_context ioContext1;
        Session* Session1 =  new Session (endpoint1, ioContext1);
 
        try {
            Session1->connectToServer ();
            ioContext1.run();
            // ...
            Session1->writeToSocket ();
            // ...
            delete Session1;
        }
        catch (...) { // Ошибка соединения.
            delete Session1;
        }
    }
    else { // ipAddress = error.
        std::cout << "error ip address: error code = " << errorCode1.value()
                        << ", message = " << errorCode1.message() << std::endl;
    }
 
    system ("pause");
    return 0;
}


Добавлено через 5 минут
Думаю, тема считается закрытой. Цель достигнута ))

Спасение утопающего - дело рук самого утопающего )
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
23.08.2025, 22:59
Помогаю со студенческими работами здесь

Клиент/сервер: клиент посылает серверу слово; определить, является ли это слово палиндромом
Осуществить взаимодействие клиента и сервера на основе протокола TCP/IP. Функционирование клиента и...

Клиент-Серверное приложение. Как сделать, чтобы сервер сам отправлял сообщения на клиент
Добрый день всем. Проблема заключается в следующем: Есть клиент-серверное приложение, хочу...

Передача файлов клиент-сервер-клиент используя Socket
Добрый день! Срочно нужна помощь. Мне нужно передать файлы с клиента на сервер и обратно,...

Найти ошибки, которые не дают сделать асинхронный сервер
Хотелось мне сделать обертку вокруг асио. Чтобы обьект класса в одно время был сервером, в другое...

3-х поточный асинхронный сервер
Нажмакал я на клавиатуре свой первый 3-х поточный асинхронный сервер (просто печатает все, что ему...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути
Programma_Boinc 01.01.2026
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути Сочетание глобально распределённой вычислительной мощности и инновационных. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru