wanshenmean
2026-03-06 aefdecd0aa3226b7d00d1dc764241b82658b3be8
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
using System.Net;
using System.Net.Sockets;
using System.Text;
 
var options = ClientOptions.FromArgs(args);
 
Console.WriteLine($"准备启动 {options.ClientCount} 个客户端,连接到 {options.ServerHost}:{options.ServerPort}");
 
var tasks = Enumerable.Range(0, options.ClientCount)
    .Select(i => RunClientAsync(i + 1, options))
    .ToArray();
 
await Task.WhenAll(tasks);
 
static async Task RunClientAsync(int clientId, ClientOptions options)
{
    var localPort = options.StartLocalPort + clientId - 1;
 
    using var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    client.Bind(new IPEndPoint(IPAddress.Any, localPort));
 
    await client.ConnectAsync(options.ServerHost, options.ServerPort);
    Console.WriteLine($"客户端#{clientId} 已连接,本地端口: {localPort}");
 
    await WriteMessageAsync(client, clientId, $"Hello from client #{clientId}");
    await ReadMessageAsync(client, clientId);
 
    client.Shutdown(SocketShutdown.Both);
}
 
static async Task WriteMessageAsync(Socket client, int clientId, string message)
{
    var framedMessage = $"<START>{message}<END>";
    var sendBuffer = Encoding.UTF8.GetBytes(framedMessage);
    await client.SendAsync(sendBuffer, SocketFlags.None);
    Console.WriteLine($"客户端#{clientId} 发送: {framedMessage}");
}
 
static async Task ReadMessageAsync(Socket client, int clientId)
{
    var receiveBuffer = new byte[1024];
    var length = await client.ReceiveAsync(receiveBuffer, SocketFlags.None);
    if (length <= 0)
    {
        Console.WriteLine($"客户端#{clientId} 未接收到数据");
        return;
    }
 
    var response = Encoding.UTF8.GetString(receiveBuffer, 0, length);
    Console.WriteLine($"客户端#{clientId} 收到: {response}");
}
 
file sealed class ClientOptions
{
    public int ClientCount { get; init; } = 1;
    public string ServerHost { get; init; } = "127.0.0.1";
    public int ServerPort { get; init; } = 5000;
    public int StartLocalPort { get; init; } = 6000;
 
    public static ClientOptions FromArgs(string[] args)
    {
        var map = args
            .Select(v => v.Split('=', 2, StringSplitOptions.TrimEntries))
            .Where(parts => parts.Length == 2)
            .ToDictionary(parts => parts[0].TrimStart('-', '/').ToLowerInvariant(), parts => parts[1]);
 
        return new ClientOptions
        {
            ClientCount = GetInt(map, "count", 1),
            ServerHost = GetString(map, "host", "127.0.0.1"),
            ServerPort = GetInt(map, "serverport", 5000),
            StartLocalPort = GetInt(map, "localport", 6000)
        };
    }
 
    private static int GetInt(Dictionary<string, string> map, string key, int defaultValue)
        => map.TryGetValue(key, out var value) && int.TryParse(value, out var number) ? number : defaultValue;
 
    private static string GetString(Dictionary<string, string> map, string key, string defaultValue)
        => map.TryGetValue(key, out var value) && !string.IsNullOrWhiteSpace(value) ? value : defaultValue;
}