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

Erlang 入門範例:TCP Socket 並發客戶端

     編輯:關於C語言

程式碼結構

-module(vpl).
-export([run/2]).

-define(IP, "127.0.0.1").
-define(PORT, 1777).

run(ThreadCount, MsgCount) ->
    spawn_thread(-1, -1, ThreadCount, MsgCount).

spawn_thread(CurrentThreadNo, CurrentMsgNo, ThreadCount, MsgCount) ->
    NewThreadNo = CurrentThreadNo + 1,
    if
        NewThreadNo == ThreadCount -> ok;
        NewThreadNo < ThreadCount ->
            RetryCount = 3,
            spawn(fun() -> connect_vsp(NewThreadNo, MsgCount, RetryCount) end),
            spawn_thread(NewThreadNo, CurrentMsgNo, ThreadCount, MsgCount)
    end.

connect_vsp(ThreadNo, MsgCount, RetryCount) ->
    case gen_tcp:connect(?IP, ?PORT, [binary]) of
        {ok, Socket} ->
            io:format("connect success! ThreadNo=~w~n", [ThreadNo]),
            send_msg(Socket, MsgCount, 0, ThreadNo);
        {error, Reason} ->
            io:format("connect failed Error=~s,ThreadNo=~w~n!", [Reason, ThreadNo]),
            NewRetryCount = RetryCount - 1,
            if
                NewRetryCount > 0 ->
                    io:format("reconnect ThreadNo=~w,RetryTime=~w~n", [ThreadNo, NewRetryCount]),
                    connect_vsp(ThreadNo, MsgCount, NewRetryCount);
                NewRetryCount == 0 ->
                    io:format("reconnect ThreadNo=~w Reach Retry Max! ~n", [ThreadNo])
            end
    end.

send_msg(Socket, MsgCount, TransId, ThreadNo) ->
    MsgContentBin = <<"TestContent">>,
    Len = byte_size(MsgContentBin),
    %% 封包頭:Len(32bit) | MsgType(16bit) | Version(16bit) | Reserve(32bit)
    SendMsg = <> ++ MsgContentBin,
    if
        MsgCount == 0 ->
            ok = gen_tcp:close(Socket),
            io:format("test over ThreadNo=~w~n", [ThreadNo]);
        MsgCount > 0 ->
            case gen_tcp:send(Socket, SendMsg) of
                ok -> receive_data(Socket, MsgCount-1, TransId+1, ThreadNo);
                {error, Reason} -> io:format("send failed ~s~n!", [Reason])
            end
    end.

receive_data(Socket, MsgCount, TransId, ThreadNo) ->
    receive
        {tcp, Socket, Bin} ->
            <> = Bin,
            io:format("~w ~.16B ~n", [RecvLen, Bin]),
            send_msg(Socket, MsgCount, TransId, ThreadNo);
        {tcp_closed, Socket} ->
            io:format("close~n")
    end.

核心概念解析

概念說明
spawn/1建立新輕量級程序,傳入零參數函式,回傳 PID。
gen_tcp:connect/3建立 TCP 連線,選項 binary 以二進位制收發資料。
gen_tcp:send/2發送二進位資料,同步阻塞直到發送完成或錯誤。
receive ... end訊息匹配區塊,依模式匹配處理 {tcp, Socket, Bin}、{tcp_closed, Socket}。
二進位語法 <<...>>構造/解構位元組序列,支援位元級欄位定義(如 Len:32)。
遞迴迴圈Erlang 無傳統迴圈,以尾遞迴實現狀態機(spawn_thread、send_msg、receive_data)。

並發模型優勢

  • 每個連線獨立程序,互不阻塞,單機可支援數萬並發。
  • 錯誤隔離:單一連線崩潰不影響其他連線。
  • 熱程式碼更新:無需停機即可升級邏輯。

封包格式說明

| Len (4 bytes) | MsgType (2 bytes) | Version (2 bytes) | Reserve (4 bytes) | Payload (variable) |

發送端構造,接收端用模式匹配解析 RecvLen、MsgType,忽略其餘(_/binary)。

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