远程主机强迫关闭了一个现有的连接

编程有钱人了 2013-02-17 02:27:26
服务端

public static ManualResetEvent allDone = new ManualResetEvent(false);
private Thread yth;
private bool listenerRun = true;
Socket listener;
private const int maxsocket = 10000;
int port = 54321;
private void buttonStart_Click(object sender, EventArgs e)
{
listenerRun = true;
yth = new Thread(new ThreadStart(ListenClient));
yth.IsBackground = true;
yth.Start();
this.buttonStart.Enabled = false;
this.buttonStop.Enabled = true;
}
public void ListenClient()
{
while (listenerRun)
{
allDone.Reset();
listener.BeginAccept(new AsyncCallback(AcceptCallBack), listener);
allDone.WaitOne();
}
}
private void AcceptCallBack(IAsyncResult ar)
{
try
{
allDone.Set();
Socket sok = (Socket)ar.AsyncState;
Socket client = sok.EndAccept(ar);
StateObject state = new StateObject();
state.workSocket = client;
if(client.Available>0)
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallBack), state);

}
catch (Exception Err)
{
throw Err;
}
}
public class StateObject
{
public Socket workSocket = null;
public const int BufferSize = 1024;
public byte[] buffer = new byte[BufferSize];
}
System.Net.IPAddress[] addressList;
private void Form1_Load(object sender, EventArgs e)
{
this.buttonStop.Enabled = false;
dtu.Columns.Add("hostname", Type.GetType("System.String"));
dtu.Columns.Add("remoteip", Type.GetType("System.String"));
dtu.Columns.Add("activetime", Type.GetType("System.DateTime"));
this.dataGridView1.DataSource = dtu;
addressList = Dns.GetHostEntry(Dns.GetHostName()).AddressList;
IPAddress ipaddress = addressList[0];
IPEndPoint ipendpoint = new IPEndPoint(ipaddress, port);
listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(ipendpoint);
listener.Listen(50);
}

private void buttonStop_Click(object sender, EventArgs e)
{
this.buttonStop.Enabled = false;
this.buttonStart.Enabled = true;
listenerRun = false;
}
private void ReadCallBack(IAsyncResult ar)
{
try
{
StateObject state = (StateObject)ar.AsyncState;
Socket hander = state.workSocket;
int readbyte = hander.EndReceive(ar);
if (readbyte > 0)
{

string strmsg = Encoding.UTF8.GetString(state.buffer, 0, readbyte);
hander.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallBack), state);
}

}
catch (Exception Err)
{
throw Err;
}
}

客户端

private Socket sok;
private IPAddress ipaddress;
private IPEndPoint ipendpoint;
int port = 54321;
private void button1_Click(object sender, EventArgs e)
{
Thread th = new Thread(new ThreadStart(Get_TEst));
th.IsBackground = true;
th.Start();
this.buttonStart.Enabled = false;
}
private void Get_TEst()
{
try
{
ipaddress = IPAddress.Parse("192.168.1.102");

ipendpoint = new IPEndPoint(ipaddress, port);
sok = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sok.Connect(ipendpoint);

while (true)
{
byte[] sendbyte = new byte[1024];
string str = hostName + "|" + clientIP;
//string str = " ";
sendbyte = Encoding.UTF8.GetBytes(str);
sok.Send(sendbyte);
Thread.Sleep(5000);
}
}
catch (Exception Err)
{
throw Err;
}
}
string clientIP = "";
string hostName = "";
private void Form1_Load(object sender, EventArgs e)
{
clientIP = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0].ToString();
hostName = Dns.GetHostName();
}

当客户端退出的时候 出现错“远程主机强迫关闭了一个现有的连接”
经过调试 错误出现在这个函数里
private void ReadCallBack(IAsyncResult ar)
{
try
{
StateObject state = (StateObject)ar.AsyncState;
Socket hander = state.workSocket;
int readbyte = hander.EndReceive(ar);
if (readbyte > 0)
{

string strmsg = Encoding.UTF8.GetString(state.buffer, 0, readbyte);
hander.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallBack), state);
}

}
catch (Exception Err)
{
throw Err;
}
}
请教怎么解决这个问题啊?
...全文
70075 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
大萌熊 2014-07-08
  • 打赏
  • 举报
回复
引用 3 楼 sp1234 的回复:
而不需要把这这类异常作为一个编程bug处理 运行时(而非可以测试时)当对方意外断开,那么关闭本地的连接就行了。不需要当作bug处理。
为什么你长的那么像王小萌?
eloveo 2013-02-17
  • 打赏
  • 举报
回复
你这是socket tcp/ip 通信,出现这种情况是属正常现象,socket一但连接,客、服务端都有一个端口处于监听模式,一但一方断开,别一方马上做出响应,同样抛出异常。 需要注意以下几点: 1、客户端在退出时需要将socket.close(); 2、客、服务端都需要在接收接收套接字代码块中加入try catch 并在finally将socket.close();
catchdream 2013-02-17
  • 打赏
  • 举报
回复
引用 8 楼 wangjun8868 的回复:
引用 7 楼 catchdream 的回复: 肯定崩啊,你catch 最后不是又 throw 了 catch (Exception Err) { throw Err; } 这不是吗
对啊,你在catch里面 throw Err; 那么就肯定抛到最外层,如果一直没有其他的catch,被运行时扑捉到,就是程序崩溃了
编程有钱人了 2013-02-17
  • 打赏
  • 举报
回复
引用 7 楼 catchdream 的回复:
肯定崩啊,你catch 最后不是又 throw 了
catch (Exception Err) { throw Err; } 这不是吗
catchdream 2013-02-17
  • 打赏
  • 举报
回复
肯定崩啊,你catch 最后不是又 throw 了
编程有钱人了 2013-02-17
  • 打赏
  • 举报
回复
引用 4 楼 bdmh 的回复:
抓一下包,看看是哪方断开的,可能是某些原因导致服务端断开了与你的连接,比如超时,或者你创建了重复的连接,而只有其中一条连接活动,当其他连接收到服务端发来的断开信息时,在你客户端报错
错误在这 int readbyte = hander.EndReceive(ar); 我放在try里面了 为什么服务器端还崩溃呢?
catchdream 2013-02-17
  • 打赏
  • 举报
回复
2种方法,一种是在捕获异常里面解析异常代码(10054),这种情况就是客户端关闭程序等,你只要进行服务器端的扫尾工作(释放资源等);另外一种复杂点,通过命令包双方来解析,客户端在断开连接前,先发送断开命令包(或者Logout包)。服务器端解析命令包,如果是这种包,就不再调用下一轮的 BeginReceive。。
bdmh 2013-02-17
  • 打赏
  • 举报
回复
抓一下包,看看是哪方断开的,可能是某些原因导致服务端断开了与你的连接,比如超时,或者你创建了重复的连接,而只有其中一条连接活动,当其他连接收到服务端发来的断开信息时,在你客户端报错
  • 打赏
  • 举报
回复
而不需要把这这类异常作为一个编程bug处理 运行时(而非可以测试时)当对方意外断开,那么关闭本地的连接就行了。不需要当作bug处理。
devmiao 2013-02-17
  • 打赏
  • 举报
回复
http://stackoverflow.com/questions/3389401/c-sharp-an-existing-connection-was-forcibly-closed-by-the-remote-host-socket-pr
  • 打赏
  • 举报
回复
没有看你的代码。 通讯系统是跨进程的系统设计,在表现层去try...catch是非常正确的。对于这类问题完全可以在catch中解决,就好像internet网络时通时断一样,你需要在业务逻辑上习惯并且应对,而不需要把这这类一场作为一个编程bug处理。

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧