C# 如何在c语言中关闭tcp套接字连接#
我有一个来自youtube的tcp套接字聊天应用程序 服务器端C# 如何在c语言中关闭tcp套接字连接#,c#,sockets,tcp,C#,Sockets,Tcp,我有一个来自youtube的tcp套接字聊天应用程序 服务器端 int i; TcpListener server = new TcpListener(IPAddress.Any, 1980); NetworkStream stream; TcpClient client; byte[] datalength = new byte[4]; public Form1() { InitializeComponent(); } public void ServerReceive() {
int i;
TcpListener server = new TcpListener(IPAddress.Any, 1980);
NetworkStream stream;
TcpClient client;
byte[] datalength = new byte[4];
public Form1()
{
InitializeComponent();
}
public void ServerReceive()
{
stream = client.GetStream();
new Thread(() =>
{
while ((i = stream.Read(datalength, 0, 4)) != 0)
{
byte[] data = new byte[BitConverter.ToInt32(datalength, 0)];
stream.Read(data, 0, data.Length);
this.Invoke((MethodInvoker)delegate
{
txtLog.Text += System.Environment.NewLine + "Client : " + Encoding.Default.GetString(data);
});
}
}).Start();
}
public void ServerSend(string msg)
{
stream = client.GetStream();
byte[] data;
data = Encoding.Default.GetBytes(msg);
int length = data.Length;
byte[] datalength = new byte[4];
datalength = BitConverter.GetBytes(length);
stream.Write(datalength, 0, 4);
stream.Write(data, 0, data.Length);
}
private void btnSend_Click(object sender, EventArgs e)
{
try
{
if (client.Connected)
{
ServerSend(txtSend.Text);
}
}catch
{
txtLog.Text += "connection close";
}
}
private void btnListen_Click(object sender, EventArgs e)
{
server.Start();
new Thread(() =>
{
client = server.AcceptTcpClient();
if (client.Connected)
{
ServerReceive();
}
}).Start();
}
客户端
int i;
TcpClient client;
NetworkStream stream;
byte[] datalength = new byte[4];
public Form1()
{
InitializeComponent();
}
public void ClientReceive()
{
stream = client.GetStream();
new Thread(() =>
{
while ((i = stream.Read(datalength, 0, 4)) != 0)
{
byte[] data = new byte[BitConverter.ToInt32(datalength, 0)];
stream.Read(data, 0, data.Length);
this.Invoke((MethodInvoker)delegate
{
txtLog.Text += System.Environment.NewLine + "Server : " + Encoding.Default.GetString(data);
});
}
}).Start();
}
public void ClientSend(string msg)
{
stream = client.GetStream();
byte[] data;
data = Encoding.Default.GetBytes(msg);
int length = data.Length;
byte[] datalength = new byte[4];
datalength = BitConverter.GetBytes(length);
stream.Write(datalength, 0, 4);
try
{
stream.Write(data, 0, data.Length);
}
catch
{
stream.Dispose();
client.Close();
}
}
private void btnConnect_Click(object sender, EventArgs e)
{
try
{
client = new TcpClient("127.0.0.1", 1980);
ClientReceive();
txtLog.Text += Environment.NewLine+ "Connected";
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void btnSend_Click(object sender, EventArgs e)
{
if (client.Connected)
{
ClientSend(txtSend.Text);
}
}
现在,所有这些对我来说都很好,但是每次我关闭一个,我都会得到这个错误
“无法从传输连接读取数据:远程主机强制关闭了现有连接。”位于ClientReceive
()或ServerReceive
()
如果其中一个突然关闭或网络电缆突然拔出,我应该如何捕捉此错误?提前感谢在本例中,您将从
NetworkStream
对象收到一个System.IO.IOException
。此异常的嵌套值为10054(=ConnectionReset
)。要处理异常,请使用try-catch
块。比如说,
using System;
using System.IO;
using System.Net.Sockets;
stream = client.GetStream();
new Thread(() =>
{
try
{
while ((i = stream.Read(datalength, 0, 4)) != 0)
{
byte[] data = new byte[BitConverter.ToInt32(datalength, 0)];
stream.Read(data, 0, data.Length);
this.Invoke((MethodInvoker)delegate
{
txtLog.Text += System.Environment.NewLine + "Server : " + Encoding.Default.GetString(data);
});
}
}
catch (IOException ioex)
{
if (ioex.InnerException != null)
{
var sex = ex.InnerException as SocketException;
if (sex == null)
{
txtLog.Text += Environment.NewLine + "An unknown exception occurred.";
}
else
{
switch (sex.SocketErrorCode)
{
case SocketError.ConnectionReset:
txtLog.Text += Environment.NewLine + "A ConnectionReset SocketException occurred."
break;
default:
txtLog.Text += Environment.NewLine + "A SocketException occurred.";
break;
}
}
}
else
{
txtLog.Text += Environment.NewLine + "An IOException occurred.";
}
}
}).Start();
使用
try..catch
block。当我启动连接并终止客户端时,我在服务器端的“case SocketError.ConnectionReset:txtLog.Text+=Environment.NewLine+”发生了连接重置SocketException。”;中断;'跨线程操作无效:从创建控件“txtLog”的线程以外的线程访问控件“txtLog”。只能在创建控件的线程上访问控件。我没有将txtLog
作为控件进行连接。将其添加到匿名线程委托中是问题的根源。请给我一点时间,找一篇关于这个问题的文章。我认为您可以将整个catch块放在对txtLog.Invoke((MethodInvoker)委托{/*catch块here*/})的调用中代码>作为快速解决方案。