Socket 编程经验谈---如何处理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的返回

你可能感兴趣的:(Socket 编程经验谈---如何处理socket连接后服务器端或客户端的断开)