zoukankan      html  css  js  c++  java
  • 如何处理socket连接后服务器端或客户端的断开

    现象:服务器端等待客户断连接,当socket连接建立后,如果客户端异常断开,服务器会抛出异常,从而导致程序运行中断
    目标:希望服务器一直等待连接,客户端中断后程序不退出,而客户端重新恢复后可以继续保持连接
    代码:
    public class Receive
    {
    public static byte[] buffer= new byte[1024];

    public static ManualResetEvent socketEvent = new ManualResetEvent(false);
    public static Socket sListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    public static Socket handler = null;
    public static string ClientBroken = "An connection was forcibly closed by the remote host";

    public static void receive()
    {
    try
    {
    Console.WriteLine("Main ThreadID:" + AppDomain.GetCurrentThreadId());
    byte[] bytes = new byte[1024];

    IPAddress ipAddr = IPAddress.Parse("127.0.0.1");

    int Port = 10001;

    IPEndPoint EPServer = new IPEndPoint(ipAddr, Port);

    //Binding a socket
    sListener.Bind(EPServer);

    //Start listening
    sListener.Listen(10);

    while(true)
    {
    if (handler==null)
    {
    //first must make a connect
    Console.WriteLine("waiting for a connection...");
    //asychronous function for accepting connections
    sListener.BeginAccept(new AsyncCallback(AcceptCallback), sListener);
    socketEvent.WaitOne();
    handler.BeginReceive(buffer,0,buffer.Length,0,new AsyncCallback(ReceiveCallback),handler);
    socketEvent.WaitOne();
    }
    else
    {
    Console.WriteLine("waiting next message...");
    socketEvent.Reset();
    handler.BeginReceive(buffer,0,buffer.Length,0,new AsyncCallback(ReceiveCallback),handler);
    socketEvent.WaitOne();
    }
    }
    Console.ReadLine();
    }
    catch (Exception e)
    {
    Console.WriteLine(e.ToString());
    }
    Console.ReadLine();
    }


    public static void AcceptCallback(IAsyncResult ar)
    {
    try
    {
    Console.WriteLine("AcceptCallback Thread ID:" + AppDomain.GetCurrentThreadId());
    Socket listener = (Socket)ar.AsyncState;
    //new socket
    handler = listener.EndAccept(ar);
    handler.BeginReceive(buffer,0,buffer.Length,0,new AsyncCallback(ReceiveCallback),handler);
    }
    catch (Exception e)
    {
    Console.WriteLine(e.ToString());
    }
    }


    public static void ReceiveCallback(IAsyncResult ar)
    {
    string err_message=null;
    try
    {
    Console.WriteLine("ReceiveCallback Thread ID:" + AppDomain.GetCurrentThreadId());

    string content = String.Empty;
    handler = (Socket)ar.AsyncState;

    int bytesRead = handler.EndReceive(ar);

    //if there is some data...
    if (bytesRead>0)
    {
    //append it to the main string
    content += Encoding.ASCII.GetString(buffer,0,bytesRead);

    //if we encounter the end of message character
    if (content.IndexOf((char)3)> -1 || content.IndexOf((char)16)>-1)
    {
    Console.WriteLine("Read "+content.Length+" bytes from socket. \n Data:"+content);
    socketEvent.Set();
    }
    else
    {
    //otherwise receive the remaining data
    handler.BeginReceive(buffer,0,buffer.Length,0,new AsyncCallback(ReceiveCallback),handler);
    }
    }

    }
    catch(Exception e)
    {
    err_message = e.Message;
    if (err_message.IndexOf("An existing connection was forcibly closed by the remote host")> -1)
    {
    Console.WriteLine("An existing connection was forcibly closed by the remote host");
    //handler.Shutdown(SocketShutdown.Both);
    //handler.Close();

    Console.WriteLine("waiting for a connection...");
    //asychronous function for accepting connections
    sListener.BeginAccept( new AsyncCallback(AcceptCallback), sListener);
    }
    else
    {
    Console.WriteLine(e.ToString());
    }
    }
    }
    }
    说明:关键在于最后这段的异常处理,接收中断后,服务器端重新等待接收。

    现象:客户端与服务器连接,当socket连接建立后,如果服务器端异常断开,客户端会抛出异常,从而导致程序运行中断
    目标:希望客户端出现提示,服务器端中断后程序不退出,而服务器端重新恢复后可以继续保持连接
    代码:
    public class AsyncComm
    {
    public static string theResponse = "";
    public static byte[] buffer = new byte[1024];

    public static ManualResetEvent socketEvent = new ManualResetEvent(false);
    public static Socket sClient= new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    public static IPEndPoint EPServer = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 10001);

    public static void send(string data)
    {
    byte[] byteData=null;
    byteData = Encoding.ASCII.GetBytes(data);

    try
    {
    if (!sClient.Connected)
    {
    Console.WriteLine(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ffff")+" "+"Connect begining......");
    sClient.BeginConnect(EPServer, new AsyncCallback(ConnectCallback),sClient);
    socketEvent.WaitOne();
    }
    sClient.BeginSend(byteData,0,byteData.Length,0,new AsyncCallback(SendCallback),sClient);
    socketEvent.WaitOne();
    }
    catch (Exception e)
    {
    Console.WriteLine("Server side is broken...");
    socketEvent.Reset();
    return;
    }
    }

    public static void ConnectCallback(IAsyncResult ar)
    {
    try
    {
    Thread thr = Thread.CurrentThread;
    Console.WriteLine("ConnectCallback Thread State:" + AppDomain.GetCurrentThreadId());

    Socket sClient = (Socket)ar.AsyncState;
    sClient.EndConnect(ar);
    Console.WriteLine("Socket connected to " + sClient.RemoteEndPoint.ToString());
    socketEvent.Set();
    }
    catch (Exception ex)
    {
    Console.WriteLine(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ffff")+"||"+AppDomain.GetCurrentThreadId()+"||3--Level 3 Server connection is broken, waiting for Level 3 Server connection......");
    sClient= new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    socketEvent.Set();
    }
    }

    receive函数相同,可以参照写出
    说明:
    在每次发送或接收时检测当前socket是否连接,如果没有连接,就启动连接,并阻塞线程等待ConnectCallback的返回
  • 相关阅读:
    阿里云安装Mono 发生错误解决方法
    在Entity Framework 中执行Tsql语句
    WinRT app guide
    开源稳定的消息队列 RabbitMQ
    Catpic: OpenSocial Container on .NET
    MSDTC 故障排除
    HTML5 canvas图形库RGraph
    《我的WCF之旅》博文系列汇总
    TSQL Enhancement in SQL Server 2005[下篇]
    谈谈基于SQL Server 的Exception Handling[上篇]
  • 原文地址:https://www.cnblogs.com/liufei88866/p/1783075.html
Copyright © 2011-2022 走看看