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

