异步Socket写聊天程序

 Socket网络应用程序如同一般文件I/O一样在数据存取未完成的时候,整个应用程序会停滞,直到网络操作完全成功为止。若是遇上不佳的网络环境,这种情形将会严重影响整个网络程序的运作。对于网络延迟,.NET提供了自己的一组解决方法,异步操作。

Socket类提供的方法成员中包含一组专门用来进行异步操作的Socket方法。这些方法以成对出现:BeginConnect EndConnect 提供异步联机功能、BeginAccept EndAccept   提供异步接受请求、 BeginReceive EndReceive  异步接收数据、BeginSendEndSend       异步发送数据。

其实这些方法和同步相当类似,最大的差异在于AsyncCallback类派生对象,上述的异步方法接受一个AsyncCallback对象,封装回调方法,并在Socket网络操作完成之后,返回IAsyncResult接口对象。此对象被当作参数。传入回调的方法,回调的方法调用结束相关异步方法,并且传入IAsyncResult,取得相关的异步操作信息。

    public interface IAsyncResult

    public delegate void AsyncCallback (IAsyncResult ar)
    
    

ar 为异步操作的结果,获取异步操作的返回值。

 

服务端代码示例

   public static void StartListening(Socket listener, IPEndPoint localEndPoint)

    {

        listener.Bind(localEndPoint);

        listener.Listen(100);

        while (true)

        {

            //开启一个异步Socket来监听客户端连接请求,并建立回调方法AcceptCallback

            AsyncCallback cb = new AsyncCallback(AcceptCallback);

            IAsyncResult ar = listener.BeginAccept(cb, listener);

            ShowMessage("正在等待一个新连接接入...");

            ar.AsyncWaitHandle.WaitOne();  //等待连接

        }

    }

    //请求回调过程(当有一个新客户端请求连接时发生)

    private static void AcceptCallback(IAsyncResult ar)

    {

        //从IAsyncResult接口中得到客户端请求的Socket对象

        Socket listener = (Socket)ar.AsyncState;

        Socket handler = listener.EndAccept(ar);

        //StateObject:一个用户定义对象,其中包含接收操作的相关信息。当操作完成时,

        //此对象会被传递给EndReceive 委托。

        StateObject state = new StateObject();

        state.workSocket = handler;

        //建立一个接收信息的回调,以便在收到信息时激发ReceiveCallback()过程

        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,

            new AsyncCallback(ReceiveCallback), state);

    }

    //接收信息回调过程(当接收到客户端信息时发生)

    private static void ReceiveCallback(IAsyncResult ar)

    {

        String content = String.Empty;

        StateObject state = (StateObject)ar.AsyncState;

        Socket handler = state.workSocket;

        //从客户端的Socket中读取信息

        int bytesRead = handler.EndReceive(ar);

       //在此加入信息处理并显示接收到的信息

        //建立一个新的接收信息的回调,以便在收到新信息时继续本过程

        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,

                new AsyncCallback(ReceiveCallback), state);

}

 

辅助对象

    public class StateObject

    {

        public Socket workSocket = null;

        public const int BufferSize = 256;

        public byte[] buffer = new byte[BufferSize];

        public string strMsg = string.Empty;

 }

 

客户端程序

        private static ManualResetEvent connectDone = new ManualResetEvent(false);

        private static ManualResetEvent sendDone = new ManualResetEvent(false);

        private static ManualResetEvent receiveDone = new ManualResetEvent(false);

        private static String response = String.Empty;  //远程设备接收到的信息

 

        public static void StartClient(Socket client, IPEndPoint remoteEP)

        {

            client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);

            connectDone.WaitOne();

        }

        private static void ConnectCallback(IAsyncResult ar)

        {

            Socket client = (Socket)ar.AsyncState;

            client.EndConnect(ar);

            System.Diagnostics.Debug.WriteLine("连接成功:" + client.RemoteEndPoint.ToString());

            connectDone.Set();

        }

        private static void Receive(Socket client)

        {

            //创建stateObject.

            StateObject state = new StateObject();

            state.workSocket = client;

            //开始从远程设备接收信息

            client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,

                new AsyncCallback(ReceiveCallback), state);

        }

        private static void ReceiveCallback(IAsyncResult ar)

        {

            StateObject state = (StateObject)ar.AsyncState;

            Socket client = state.workSocket;

            client = state.workSocket;

            //读取信息

            int bytesRead = client.EndReceive(ar);

            //信息处理

        }

 

        public static void Send(Socket client, String data)

        {

            byte[] byteData = Encoding.UTF8.GetBytes(data);

            //向远程设备发送信息

            client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client);

        }

 

        private static void SendCallback(IAsyncResult ar)

        {

            Socket client = (Socket)ar.AsyncState;

            //所有信息已被发送

            int bytesSent = client.EndSend(ar);

        }

上面的示例只说明了异步聊天程序的原理,没有对可能发生的异常进行处理和其它辅助方法。

http://blog.csdn.net/chendazhi/archive/2006/04/21/socket

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值