You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TCP聊天程序连接时触发System.ArgumentOutOfRangeException异常求助

解决TCP聊天程序连接时的System.ArgumentOutOfRangeException异常

我一眼就看出问题出在哪了——你调用networkStream.Read时传入的第三个参数超出了目标数组的容量,直接触发了参数越界异常。

问题根源

clientSocket.ReceiveBufferSize是系统为TCP客户端分配的接收缓冲区大小,这个值默认通常在8192字节以上(甚至可能更大),但你定义的bytesFrom数组只有10025字节。当ReceiveBufferSize的值大于数组长度时,把它作为Read方法的最大读取字节数,就会超出数组的可容纳范围,自然抛出ArgumentOutOfRangeException。

修复方案

给你两个实用的解决思路,推荐用第二种更安全:

  • 思路一:根据ReceiveBufferSize初始化数组,保证数组能容纳缓冲区的所有数据
  • 思路二:直接用数组自身的长度作为Read的第三个参数,彻底避免越界风险

修改后的核心代码如下,我还加了几个额外的优化点:

static void Main(string[] args) { 
    TcpListener serverSocket = new TcpListener(8888); 
    TcpClient clientSocket = default(TcpClient); 
    int counter = 0; 
    serverSocket.Start(); 
    Console.WriteLine("Chat Server Started ...."); 
    counter = 0; 
    while (true) { 
        counter += 1; 
        clientSocket = serverSocket.AcceptTcpClient(); 
        byte[] bytesFrom = new byte[10025]; 
        string dataFromClient = null; 
        NetworkStream networkStream = clientSocket.GetStream(); 
        // 关键修改:用bytesFrom.Length替代clientSocket.ReceiveBufferSize
        int actualBytesRead = networkStream.Read(bytesFrom, 0, bytesFrom.Length); 
        // 优化:只转换实际读取到的字节,避免空字符干扰
        dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom, 0, actualBytesRead); 
        // 新增判断:防止找不到$符号导致的二次异常
        int dollarPosition = dataFromClient.IndexOf("$");
        if (dollarPosition != -1) {
            dataFromClient = dataFromClient.Substring(0, dollarPosition); 
        } else {
            // 处理异常情况,给个默认用户名
            dataFromClient = $"Guest_{counter}";
        }
        clientsList.Add(dataFromClient, clientSocket); 
        broadcast(dataFromClient + " Joined ", dataFromClient, false); 
        Console.WriteLine(dataFromClient + " Joined chat room "); 
        handleClinet client = new handleClinet(); 
        client.startClient(clientSocket, dataFromClient, clientsList); 
    } 
    clientSocket.Close(); 
    serverSocket.Stop(); 
    Console.WriteLine("exit"); 
    Console.ReadLine(); 
}

额外的重要提示

  1. 必须处理Read的返回值:networkStream.Read()返回的是实际读取到的字节数,之前直接转换整个数组会包含大量空字符,不仅浪费资源还可能导致后续字符串处理出错。
  2. 防御Substring的潜在异常:如果客户端发送的消息里没有$符号,IndexOf("$")会返回-1,这时候调用Substring(0, -1)会触发另一个参数越界异常,一定要加判断。
  3. 考虑异步改造:当前同步阻塞的代码同一时间只能处理一个客户端连接,换成AcceptTcpClientAsync和异步流操作,能让服务器同时处理多个客户端,性能会提升很多。

内容的提问来源于stack exchange,提问作者Witzig Adrien

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:23:43