如何修复TCP聊天程序中的"未连接套接字不允许操作"错误?
问题:TCP聊天程序发送消息时出现“Operation not allowed on unconnected sockets”错误
为完成学校项目,开发客户端-服务器架构的桌面聊天应用,参考TCP Listener与TcpClient教程编写代码后,尝试发送消息时弹出该错误。
原代码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Net; using System.Net.Sockets; using System.IO; namespace NetworkTest { public partial class Form1 : Form { private TcpClient client; public StreamReader STR; public StreamWriter STW; public string recieve; public string TextToSend; public Form1() { InitializeComponent(); IPAddress[] localIP = Dns.GetHostAddresses(Dns.GetHostName()); foreach(IPAddress address in localIP) { if(address.AddressFamily == AddressFamily.InterNetwork) { IPBox1.Text = address.ToString(); } } } private void StartButton_Click(object sender, EventArgs e) { TcpListener listener = new TcpListener(IPAddress.Any, int.Parse(PortBox1.Text)); listener.Start(); client = listener.AcceptTcpClient(); STR = new StreamReader(client.GetStream()); STW = new StreamWriter(client.GetStream()); STW.AutoFlush = true; backgroundWorker1.RunWorkerAsync(); backgroundWorker2.WorkerSupportsCancellation = true; } private void ConnectButton_Click(object sender, EventArgs e) { client = new TcpClient(); IPEndPoint IpEnd = new IPEndPoint(IPAddress.Parse(IPBox2.Text), int.Parse(PortBox2.Text)); try { ChatScreenBox.AppendText("Connect to Server" + "\n"); STW = new StreamWriter(client.GetStream()); STR = new StreamReader(client.GetStream()); STW.AutoFlush = true; backgroundWorker1.RunWorkerAsync(); backgroundWorker2.WorkerSupportsCancellation = true; } catch(Exception ex) { MessageBox.Show(ex.Message.ToString()); } } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { while (client.Connected) { try { recieve = STR.ReadLine(); this.ChatScreenBox.Invoke(new MethodInvoker(delegate () { ChatScreenBox.AppendText("You: " + recieve + "\n"); })); recieve = ""; } catch(Exception ex) { MessageBox.Show(ex.Message.ToString()); } } } private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e) { if (client.Connected) { STW.WriteLine(TextToSend); this.ChatScreenBox.Invoke(new MethodInvoker(delegate() { ChatScreenBox.AppendText("Me: " + TextToSend + "\n"); })); } else { MessageBox.Show("Sending Failed"); } backgroundWorker2.CancelAsync(); } private void SendButton_Click(object sender, EventArgs e) { if(MessageTextBox.Text != "") { TextToSend = MessageTextBox.Text; backgroundWorker2.RunWorkerAsync(); } MessageTextBox.Text = ""; } } }
错误原因
- 客户端未执行连接操作:在
ConnectButton_Click方法中,创建TcpClient实例后,没有调用client.Connect(IpEnd)建立与服务器的连接,直接尝试获取套接字流,此时套接字处于未连接状态。 - 流对象绑定未连接套接字:即使连接未建立,代码仍创建了
StreamWriter和StreamReader,这些对象依赖未连接的套接字,发送消息时触发“不允许在未连接套接字上操作”的错误。 - 连接状态校验不严谨:发送消息前未检查
client是否已成功连接,仅判断消息非空就触发发送逻辑。
解决方案
1. 修复客户端连接逻辑
修改ConnectButton_Click方法,先执行连接操作,确认连接成功后再创建流对象:
private void ConnectButton_Click(object sender, EventArgs e) { client = new TcpClient(); IPEndPoint IpEnd = new IPEndPoint(IPAddress.Parse(IPBox2.Text), int.Parse(PortBox2.Text)); try { // 先建立与服务器的连接 client.Connect(IpEnd); ChatScreenBox.AppendText("已连接到服务器\n"); // 连接成功后再初始化流 STW = new StreamWriter(client.GetStream()); STR = new StreamReader(client.GetStream()); STW.AutoFlush = true; backgroundWorker1.RunWorkerAsync(); backgroundWorker2.WorkerSupportsCancellation = true; } catch(Exception ex) { MessageBox.Show("连接失败:" + ex.Message); } }
2. 增加发送前的连接校验
修改SendButton_Click方法,确保客户端已连接后再执行发送:
private void SendButton_Click(object sender, EventArgs e) { string message = MessageTextBox.Text.Trim(); if(!string.IsNullOrEmpty(message) && client != null && client.Connected) { TextToSend = message; backgroundWorker2.RunWorkerAsync(); } else { MessageBox.Show("请先连接到服务器"); } MessageTextBox.Text = ""; }
3. 优化资源释放(可选)
在窗体关闭时释放TCP资源,避免端口占用:
protected override void OnFormClosing(FormClosingEventArgs e) { base.OnFormClosing(e); // 关闭客户端连接 client?.Close(); // 如果将TcpListener声明为类成员,此处也需停止 // listener?.Stop(); }
内容的提问来源于stack exchange,提问作者Whole-Humor
相关产品推荐
相关产品推荐

