LINUX.ORG.RU

На чем сейчас многопоточные TCP сервера на си++ пишут

 


0

4

Добрый день, много лет назад писал простенькие сетевые приложения на си, затем было Qt с их TcpSocket, потом boost asio, трогал все это добро палкой лет 5 назад. Сейчас возникла потребность в создании многопоточного сервера на си++. Какие библиотеки для этого сейчас модно и молодежно использовать. Решил глянуть по hh.ru что там требуют. boost, asio, poco вообще как-то не в почете. На чем сейчас это все делают и какую книжку почитать? Все что нашел это пара книг по си++ и ACE, но они кажется устарели.

★
Ответ на: комментарий от da17

ЛОЛ) А как-нибудь на си++ или я реально отстал и проще выучить го чем на си++ это писать?

Го почти что не нужно учить. https://tour.golang.org

anonymous
()

Сейчас возникла потребность в создании многопоточного сервера на си++.

Постыдились бы.

RazrFalcon ★★★★★
()
Ответ на: комментарий от da17
package main

import (
    "fmt"
    "net/http"
)

func main() {
    var s http.Server
    s.Addr = "127.0.0.1:5000"
    s.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Reqeust) {
        fmt.Fprintf(w, "[%s] %s: Hello!", r.Method, r.URL.Path)
    })
    s.ListenAndServe()
}

anonymous
()
Ответ на: комментарий от da17

Go, Rust. Java/Erlang для эстетов.

Да и что это за потребность такая? Неужто преждевременная оптимизация. Ну тогда и питона хватит.

RazrFalcon ★★★★★
()

Зависит от того, что за сервера.

POCO никогда производительностью не отличался, поэтому его применяли там, где важнее быстро работающую версию выкатить, чем сделать эффективную реализацию.

ACE практически остановился в своем развитии. Но если хочется чего-то производительного и в стиле «Си с классами», то до сих пор еще актуально.

(Boost)Asio — современно, удобно, популярно. Плюс на его основе делают Networking TS, так что когда-нибудь в стандартной библиотеке C++ будут средства для работы с сетью, выросшие из Asio. Поэтому на перспективу Asio предпочтителен. К тому же Asio можно взять и без Boost-е.

Так же используются libuv, libevent/libev. Как напрямую, так и обернутые в современный (и не очень) C++.

Если нужно не просто абстрактный многопоточный сервер, а, например, многопоточный HTTP-сервер, то для этого есть специализированные библиотеки.

eao197 ★★★★★
()
Ответ на: комментарий от RazrFalcon

Неужто преждевременная оптимизация.

Преждевременная оптимизация — это писать веб-приложение на Си или плюсах. Не?

anonymous
()
Ответ на: комментарий от RazrFalcon

Да всё. Я просто не так понял сначала. Забей короче.

anonymous
()

К слову только вчера была новость о «новом» HTTP фремворке для C++17: drogon

Если вам норм писать такой ужас - то всё ок.

app.registerHandler("/test?username={1}",
                    [](const HttpRequestPtr& req,
                       std::function<void (const HttpResponsePtr &)> &&callback,
                       const std::string &name)
                    {
                        Json::Value json;
                        json["result"]="ok";
                        json["message"]=std::string("hello,")+name;
                        auto resp=HttpResponse::newHttpJsonResponse(json);
                        callback(resp);
                    },
                    {Get,"LoginFilter"});
RazrFalcon ★★★★★
()
Ответ на: комментарий от da17

и проще выучить го чем на си++ это писать?

Где-то так, да

vertexua ★★★★★
()
Ответ на: комментарий от anonymous

Задача в более общем виде, с минимальными задержками по инициативе сервера дать команды пары сотен устройств. Ранее все было сделано так, устройства по таймеру обращались к серверу посредством get запроса, а на сервере отрабатавали cgi скрипты. Как я вижу решение. Устройства устанавливают TCP соединение с сервером и ожидают от него комманд. Сам сервер с устройствами соединение установить не может, они многие за NAT.

da17 ★
() автор топика
Ответ на: комментарий от da17

Ну для такого Go это примерно час работы. Даже если ты не сильно в Go. Компиляется, работает, годно.

anonymous
()
Ответ на: комментарий от da17

может пора использовать очереди сообщений? MQTT например если хочется легковесного.

anonymous
()
Ответ на: комментарий от da17

Там вон выше тебе тутор кинули. его потыкай.

anonymous
()
Ответ на: комментарий от da17

Устройства устанавливают TCP соединение с сервером и ожидают от него комманд.

Берете MQTT и любую из его реализаций, не паритесь и не изобретаете велосипедов.

eao197 ★★★★★
()
Ответ на: комментарий от RazrFalcon

К слову только вчера была новость о «новом» HTTP фремворке для C++17: drogon

Он далеко не новый. Ну и не так уж все страшно выглядит. Особенно если с Boost.Beast сравнивать.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Коллега который работал, говорит, что MQTT это если устройствам надо отсылать телеметрию, а мне наоборот, устройствам отсылать команды.

da17 ★
() автор топика
Ответ на: комментарий от da17

MQTT это про пересылку мессаджей, а чем их нагрузить: телеметрией или командами это тебе решать.

anonymous
()
Ответ на: комментарий от da17

Коллега который работал, говорит, что MQTT это если устройствам надо отсылать телеметрию, а мне наоборот, устройствам отсылать команды.

Пипец, в каком колхозе вы работаете?

В MQTT клиент подписывается на топик и получает опубликованные в этом топике сообщения. Кто уже публикует эти сообщения – другой клиент или сам сервер – не суть важно.

Поэтому делается, например, так:

  • поднимается MQTT-шный брокер;
  • с одной стороны к этому брокеру подключается управляющая софтина (сервер в вашем понимании);
  • с другой стороны к этому же брокеру подключаются клиенты;
  • клиенты подписываются на топики (например, вида /clients/all/commands или clients/client-15-42/commands);
  • управляющая софтина публикует команду в неком топике и эта команда доставляется клиентам, которые подписаны на этот топик. Например, если все клиенты подписаны на /clients/all/commands и туда публикуется сообщение M, то все клиенты это сообщение и получат. Если же какой-то единственный клиент подписан на /clients/client-15-42/commands и сообщение K публикуется в этот тупик, то только один клиент получит данное сообщение.

В обратную сторону работает так же, только там подписчиком выступает сервер, а публикацией занимаются клиенты.

А коллеге своему матчасть посоветуйте подучить. Или хотя бы кругозор расширить. Понабирают войтишников по объявлению, а те потом городские легенды среди таких же распространяют.

eao197 ★★★★★
()
Последнее исправление: eao197 (всего исправлений: 1)
Ответ на: комментарий от eao197

А с какой скоростью клиенты получают сообщения от сервера? Т.е. они периодически опрашивают его или там уже реализовано все это внутри TCP/IP.

da17 ★
() автор топика
Ответ на: комментарий от da17

получают сразу, об этом можешь не беспокоится. твоя задача просто обработать сообщение.

anonymous
()
Ответ на: комментарий от da17

Это все реализовано поверх TCP/IP. Причем там же уже сразу реализованы пинги, чтобы канал не протухал, если долго активности нет. И, плюс к тому, в нормальных реализациях клиентов MQTT реализовано автоматическое переподключение к брокеру при разрывах связи (ЕМНИП).

eao197 ★★★★★
()
Ответ на: комментарий от da17

Так зачем это в вакансии указывать? Иногда просто пишут boost. Иногда вообще не пишут. Это же библиотека.

anonymous
()
Ответ на: комментарий от WitcherGeralt

Какие еще промисы в роутах-то? Выглядит как типикал экспресс-миддлваре, только все типы объявлены.

anonymous
()
Ответ на: комментарий от da17

Лонг-поллинг по хттпс в цикле спасет пацана. Сервер пишется на любой асинхронной коленке с очередью. Можно конечно всякие mq заюзать, но прозрачность того вряд ли стоит.

Подумай над сроком протухания команды при отвале клиента от сети, об атомарности серий команд, валидности старых команд в очереди и прочем. Вангую в этих ихних mq это не самые тривиальные места, т.к. момент отсылки очереди наверняка скрыт за горой абстракций.

anonymous
()
Ответ на: комментарий от da17

А как-нибудь на си++

Тогда явно не стоит слушать RazrFalcon и любителей Go. Это плюсохейтеры.

Deleted
()
Ответ на: комментарий от RazrFalcon
using std::string_literals::operator""s;
"ass"s+"ssa";
anonymous
()

Пиши на scala. Быстро, стильно, надежно, молодежно и все в функциональном стиле.

import java.net.InetSocketAddress

import akka.actor.{ActorSystem, Props, Actor}
import akka.io.{Tcp, IO}
import akka.io.Tcp._
import akka.util.ByteString

class TCPConnectionManager(address: String, port: Int) extends Actor {
  import context.system
  IO(Tcp) ! Bind(self, new InetSocketAddress(address, port))

  override def receive: Receive = {
    case Bound(local) =>
      println(s"Server started on $local")
    case Connected(remote, local) =>
      val handler = context.actorOf(Props[TCPConnectionHandler])
      println(s"New connnection: $local -> $remote")
      sender() ! Register(handler)
  }
}

class TCPConnectionHandler extends Actor {
  override def receive: Actor.Receive = {
    case Received(data) =>
      val decoded = data.utf8String
      sender() ! Write(ByteString(s"You told us: $decoded"))
    case message: ConnectionClosed =>
      println("Connection has been closed")
      context stop self
  }
}

object Server extends App {
  val system = ActorSystem()
  val tcpserver = system.actorOf(Props(classOf[TCPConnectionManager], "localhost", 8080))
}

не благодари
Miha
()
Ответ на: комментарий от anonymous

Я не совсем понял, что такое лонг-поллинг, но спасибо. Т.к. не мог сформулировать что я хочу, а хочу я в первую очередь «прозрачности», что бы все понятно было, вот мы клиенту команду отправляем путем записи в сокет, вот он это квитирует, как следить за тем что клиент не отвалился. Например требуется на устройстве регулировать мощность передатчика. Пока даже не решил как это отслеживать.

da17 ★
() автор топика
Ответ на: комментарий от Miha

Всякие Qt использовать не очень хочу, т.к. там слишком много абстракций и т.к. использую плотно, постоянно натыкаюсь на разные ошибки.

da17 ★
() автор топика
Ответ на: комментарий от Harald

Не слушай его, тс. libuv под нагрузкой подыхает. Я пытался использовать, завёл пачку багов в багтрекере у них.

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от DELIRIUM

я не планирую нагрузку, но вот например нескольким сотням приборов дать команду на перезагрузку и обратно квитанцию получить. Это нагрузка или не нагрузка? Не очень ориентируюсь в терминах.

da17 ★
() автор топика
Ответ на: комментарий от Harald

да я тут писал уже давно, что не мог аппаратное декодирование задействовать, исправили только в Qt 5.10, еще там несколько лет назад столкнулся с кривым кодом в работе сокетов, когда Qt 5.6 только выкатили. Наелся в общем.

da17 ★
() автор топика
Вы не можете добавлять комментарии в эту тему: топик перемещен в архив.