现有连接被远程主机强行关闭
Posted
技术标签:
【中文标题】现有连接被远程主机强行关闭【英文标题】:An existing connection was forcibly closed by remote host 【发布时间】:2019-12-14 19:33:10 【问题描述】:我的 C# windows 表单的一部分是点对点(只有两个用户)聊天。 我使用.Net Socket。
我想做的是,只要两个用户都有空,他们就可以聊天。但是,当其中一个关闭程序然后再次打开它时,会出现许多问题。或者当只有一个在线时,我会收到此异常。
“一个现有的连接被远程主机强行关闭”。
我尝试使用 Socket.Close 和 Socket.ShutDown。我还尝试通过再次定义套接字变量来重新启动它。一切似乎都不起作用。即使使用不同的库或方法,我也愿意接受任何建议。
代码如下:
namespace TextChatApp
public partial class Form1 : Form
//attributes:
Socket sck;
EndPoint epLocal, epRemote;
public Form1()
InitializeComponent();
sck = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sck.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
textBox1.Text=GetLocalIP();
textBox3.Text = GetLocalIP();
textBox2.Text = "8001";
textBox4.Text = "8000";
send.Enabled = false;
connectEndPoint();
InitTimer();
private void MessageCallBack(IAsyncResult aResult)
try
int size = sck.EndReceiveFrom(aResult, ref epRemote);
if(size>0)
byte[] receivedData = new byte[1500];
receivedData = (byte[])aResult.AsyncState;
ASCIIEncoding eEncoding = new ASCIIEncoding();
string receivedMessage = eEncoding.GetString(receivedData);
listBox1.Items.Add("From a friend: "+receivedMessage);
byte[] buffer = new byte[1500];
sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageCallBack), buffer);
catch(Exception exp)
MessageBox.Show("Exception Small Chat: " + exp.ToString());
private void start_Click(object sender, EventArgs e)
public void connectEndPoint()
try
epLocal = new IPEndPoint(IPAddress.Parse(textBox1.Text), Convert.ToInt32(textBox2.Text));
sck.Bind(epLocal);
epRemote = new IPEndPoint(IPAddress.Parse(textBox3.Text), Convert.ToInt32(textBox4.Text));
sck.Connect(epRemote);
byte[] buffer = new byte[1500];
sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageCallBack), buffer);
start.Enabled = false;
start.Text = "Connected";
send.Enabled = true;
textBox5.Focus();
catch (Exception exp)
private void send_Click(object sender, EventArgs e)
try
System.Text.Encoding encoding = System.Text.Encoding.UTF8;
byte[] msg = new byte[1500];
msg = encoding.GetBytes(textBox5.Text);//
sck.Send(msg);
listBox1.Items.Add("You: " + textBox5.Text);
textBox5.Clear();
catch(Exception exp)
MessageBox.Show("Exception Small Chat: " + exp.ToString());
【问题讨论】:
哪一行抛出异常? int size = sck.EndReceiveFrom(aResult, ref epRemote); 抛出的SocketException
应该有一个ErrorCode
属性;是否对应Windows Sockets Error Codes list中的一个,在你不同的场景下,你每次得到的都是一样的吗?
在这个异常之后一切都开始出错了。 0x80004005。当其中一个点发送数据而另一个点因任何原因离线时,就会发生这种情况。为了避免这种情况,我尝试采用不同的方法在发送数据之前检查一个点是否在线。但是,我还没有解决。
【参考方案1】:
我想我解决了自己的问题。 由于我在发送数据时触发了异常并且端点关闭或未连接,因此我应该在发送数据之前检查它是否已连接。
但是,没有直接的方法可以确定端点是否已连接。 因为当我发送数据并且端点关闭时它会触发异常,所以异常成为我的指标,表明端点关闭并且连接丢失。所以我要做的是在“Catch”语句中再次创建 Socket,并每隔一段时间再试一次,直到 Socket 再次连接。
我每次触发异常时都重新创建Socket是因为Socket会不稳定,会导致很多连接问题。所以最好重新创建它而不是不稳定。
这是我包含的代码
private void MessageCallBack(IAsyncResult aResult)
try
int size = sck.EndReceiveFrom(aResult, ref epRemote);
if(size>0)
byte[] receivedData = new byte[1500];
receivedData = (byte[])aResult.AsyncState;
ASCIIEncoding eEncoding = new ASCIIEncoding();
string receivedMessage = eEncoding.GetString(receivedData);
listBox1.Invoke(new MethodInvoker(delegate
listBox1.Items.Add("From a friend: " + receivedMessage); ));
byte[] buffer = new byte[1500];
sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None,
ref epRemote, new AsyncCallback(MessageCallBack), buffer);
catch(Exception exp)
/* here is the solution, when the Catch is triggered, close the
socket and recreate it to avoid the issues that I been having of
not sending messages and instability. I also added some functions
that would keep sending the status and //being checked on the other
side in order to keep online/offline status.*/
sck.Close();
sck = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,
ProtocolType.Udp);
sck.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReuseAddress, true);
connectEndPoint();
//MessageBox.Show("Exception Small Chat: " + exp.ToString());
【讨论】:
以上是关于现有连接被远程主机强行关闭的主要内容,如果未能解决你的问题,请参考以下文章
System.Net.Sockets.SocketException:'现有连接被远程主机强行关闭'