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
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.