Socket 异步 长连接 多点 服务端代码(C#)

今日研究socket通讯,应用情景是,一台服务器要链接多个终端设备。

其中服务器做server端,终端做client端,client需要长连接到server,如果中途通讯中断,server需要能够侦测到这个事件,释放连接资源。重新等待client的连接。

在网上参考了不少文章,其中有一篇文章的内容比较相符,不过这篇文章中的连接不是长连接。

稍作修改后,实现了异步 长连接  可以多终端同时通讯。

贴出代码如下:(代码中socket的释放是做了一个30秒的定时,可以替换成其他条件判断,在需要时释放资源)

 代码结构很清晰,不做注释了。。


usingSystem;

using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;


// State object for reading client dataasynchronously
public class StateObject
{
    // Client socket.
    public Socket workSocket = null;
    // Size of receive buffer.
    public const int BufferSize =1024;
    // Receive buffer.
    public byte[] buffer = newbyte[BufferSize];
    // Received data string.
    public StringBuilder sb = newStringBuilder();
}


public class AsynchronousSocketListener
{
    // Thread signal.
    public static ManualResetEventallDone = new ManualResetEvent(false);


    publicAsynchronousSocketListener()
    {
    }


    public static void StartListening()
    {
        // Data buffer forincoming data.
        byte[] bytes = newByte[1024];


        // Establish thelocal endpoint for the socket.
        // The DNS name ofthe computer
        // running thelistener is "host.contoso.com".
       // IPHostEntryipHostInfo = Dns.Resolve(Dns.GetHostName());
       // IPAddressipAddress = ipHostInfo.AddressList[0];
        IPAddress ipAddress= IPAddress.Any;
        IPEndPointlocalEndPoint = new IPEndPoint(ipAddress, 13000);


        // Create a TCP/IPsocket.
        Socket listener =new Socket(AddressFamily.InterNetwork,
        SocketType.Stream,ProtocolType.Tcp);


        // Bind the socketto the local endpoint and listen for incoming connections.
        try
        {
            listener.Bind(localEndPoint);
           listener.Listen(100);


            while(true)
            {
               // Set the event to nonsignaled state.
               allDone.Reset();


               // Start an asynchronous socket to listen for connections.
               Console.WriteLine("Waiting for a connection...");
               listener.BeginAccept(
               new AsyncCallback(AcceptCallback),
               listener);


               // Wait until a connection is made before continuing.
               allDone.WaitOne();
            }


        }
        catch (Exception e)
        {
           Console.WriteLine(e.ToString());
        }


       Console.WriteLine("\nPress ENTER to continue...");
        Console.Read();


    }


    public static voidAcceptCallback(IAsyncResult ar)
    {
        int i = 0;
        // Signal the mainthread to continue.
        allDone.Set();


        // Get the socketthat handles the client request.
        Socket listener =(Socket)ar.AsyncState;
        Socket handler =listener.EndAccept(ar);


        // Create the stateobject.
        StateObject state =new StateObject();
        state.workSocket =handler;
        while (true)
        {
            
           handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
            newAsyncCallback(ReadCallback), state);
           Thread.Sleep(100);
            i +=1;
           //Socket will colse after 30 seconds
            if(i>300)
            {
               handler.Shutdown(SocketShutdown.Both);
               handler.Close();
               break ;
            }
        }
              
    }


    public static voidReadCallback(IAsyncResult ar)
    {
        String content =String.Empty;


        // Retrieve thestate object and the handler socket
        // from theasynchronous state object.
        StateObject state =(StateObject)ar.AsyncState;
        Socket handler =state.workSocket;


        // Read data fromthe client socket. 
        int bytesRead =handler.EndReceive(ar);


        if (bytesRead >0)
        {
            //There might be more data, so store the data received so far.
           state.sb.Append(Encoding.ASCII.GetString(
           state.buffer, 0, bytesRead));


            //Check for end-of-file tag. If it is not there, read 
            //more data.
           content = state.sb.ToString();
            if(content.IndexOf("<EOF>") > -1)
            {
               // All the data has been read from the 
               // client. Display it on the console.
               Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
               content.Length, content);
               // Echo the data back to the client.
               Send(handler, content);
            }
            else
            {
               // Not all data received. Get more.
               handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
               new AsyncCallback(ReadCallback), state);
            }
        }
    }


    private static void Send(Sockethandler, String data)
    {
        // Convert thestring data to byte data using ASCII encoding.
        byte[] byteData =Encoding.ASCII.GetBytes(data);


        // Begin sending thedata to the remote device.
       handler.BeginSend(byteData, 0, byteData.Length, 0,
        newAsyncCallback(SendCallback), handler);
    }


    private static voidSendCallback(IAsyncResult ar)
    {
        try
        {
            //Retrieve the socket from the state object.
            Sockethandler = (Socket)ar.AsyncState;


            //Complete sending the data to the remote device.
            intbytesSent = handler.EndSend(ar);
           Console.WriteLine("Sent {0} bytes to client.", bytesSent);


           //handler.Shutdown(SocketShutdown.Both);
           //handler.Close();


        }
        catch (Exception e)
        {
           Console.WriteLine(e.ToString());
        }
    }


 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值