首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Muduo網絡編程示例之一:五個經典 TCP 協議實作

     編輯:關於C語言

前言

在網絡編程的學習曲線中,掌握幾個最基礎的 TCP 協議是絕佳的切入點。本文將帶領讀者透過 Muduo 網絡庫,逐步實作 Discard、Daytime、Time 等經典協議,並深入剖析長連線與短連線的事件處理差異。

Discard 協議:最簡單的長連線

Discard 協議(RFC 863)的行為極其單純:伺服端接受連線後,只需處理「訊息到達」事件,將收到的資料直接丟棄並記錄日誌。在 Muduo 中,核心邏輯僅需實作 onMessage 回呼:

void DiscardServer::onMessage(const TcpConnectionPtr& conn,
                              Buffer* buf,
                              Timestamp time)
{
    string msg(buf->retrieveAsString()); // 取回所有讀到的資料
    LOG_INFO << conn->name() << " discards " << msg.size()
             << " bytes at " << time.toString();
}

其餘皆為樣板程式碼:定義 DiscardServer 類別,持有 TcpServer 成員,在建構函式中註冊 onConnection 與 onMessage 回呼,最後在 main() 中啟動 EventLoop 即可運行。

Daytime 協議:短連線的典範

Daytime(RFC 867)屬於短連線協議:連線建立後,伺服端立即發送當前時間字串,隨即主動關閉連線。因此只需關注「連線已建立」事件:

void DaytimeServer::onConnection(const TcpConnectionPtr& conn)
{
    LOG_INFO << "DaytimeServer - " << conn->peerAddress().toHostPort()
             << " -> " << conn->localAddress().toHostPort()
             << " is " << (conn->connected() ? "UP" : "DOWN");
    if (conn->connected())
    {
        conn->send(Timestamp::now().toFormattedString() + "\n");
        conn->shutdown(); // 主動斷開
    }
}

客戶端可用 nc 127.0.0.1 2013 測試,即可收到類似 2011-02-02 03:31:26.622647 的回應。

Time 協議:32 位元整數的時間戳

Time 協議(RFC 868)與 Daytime 類似,差別在於回傳的是網路序的 32 位元整數,代表自 1970-01-01 00:00:00 UTC 以來的秒數(即經典的「2038 年問題」來源)。處理邏輯幾乎相同:

void TimeServer::onConnection(const TcpConnectionPtr& conn)
{
    if (conn->connected())
    {
        int32_t now = sockets::hostToNetwork32(static_cast<int>(::time(NULL)));
        conn->send(&now, sizeof now); // 發送 4 個位元組
        conn->shutdown();
    }
}

小結

這三個協議雖然簡單,卻完美展示了 Muduo 以事件驅動、回呼為核心的設計哲學:長連線處理 onMessage,短連線處理 onConnection。掌握這些基礎,便能輕鬆延伸至更複雜的應用層協議開發。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved