三种方式实现异步socket

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using Wintellect.Threading.AsyncProgModel;

namespace ExtensionTest
{
    /*
     * 没有异常处理 前两种还没有实现持续接收
     * AsyncEnumerator来自jeffrey rich的Wintellect
     */

    public class NetWork
    {
        private const string ip = "localhost";
        private const int port = 10101;

        private IPEndPoint endPoint;
        private Socket server;

        public NetWork()
        {
            endPoint = new IPEndPoint(Dns.GetHostEntry(ip).AddressList[0], port);

            server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
            server.Bind(endPoint);
            server.Listen(10);
        }

        public void StartListening()
        {
            server.BeginAccept(AcceptCallback, server);
        }

        public void StartListeningWithIterator()
        {
            AsyncEnumerator asycn = new AsyncEnumerator();
            asycn.Execute(this.StartAsync(asycn));
        }

        private void AcceptCallback(IAsyncResult asyncResult)
        {
            Socket server = asyncResult.AsyncState as Socket;
            if (server != null)
            {
                Socket receiveSocket = server.EndAccept(asyncResult);

                byte[] buffer = new byte[256];

                receiveSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReceiveCallback, new State(receiveSocket, buffer));

                //
                this.StartAsync(receiveSocket);
            }
        }

        private void ReceiveCallback(IAsyncResult asyncResult)
        {
            State state = asyncResult.AsyncState as State;

            if (state != null)
            {
                int receBytes = state.Socket.EndReceive(asyncResult);
                if (receBytes > 0)
                    state.Socket.BeginSend(state.Bytes, 0, receBytes, SocketFlags.None, SendCallback, state.Socket);
            }
        }

        private void SendCallback(IAsyncResult asyncResult)
        {
            Socket socket = asyncResult.AsyncState as Socket;
            if (socket != null)
            {
                socket.EndSend(asyncResult);
            }
        }

        private IEnumerator<int> StartAsync(AsyncEnumerator enumerator)
        {
            server.BeginAccept(enumerator.End(), null);

            yield return 1;

            Socket receiveSocket = server.EndAccept(enumerator.DequeueAsyncResult());

            byte[] buffer = new byte[256];

            receiveSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, enumerator.End(), null);

            yield return 1;

            int receLength = receiveSocket.EndReceive(enumerator.DequeueAsyncResult());

            if (receLength > 0)
            {
                receiveSocket.BeginSend(buffer, 0, receLength, SocketFlags.None, enumerator.End(), null);

                yield return 1;

                receiveSocket.EndSend(enumerator.DequeueAsyncResult());
            }
            else
                yield break;
        }

        private void StartAsync(Socket socket)
        {
            AsyncCallback callback = null;

            byte[] buffer = new byte[256];
            callback = receResult =>
                           {
                               int receLength = socket.EndReceive(receResult);

                               if (receLength > 0)
                               {
                                   socket.BeginSend(buffer, 0, receLength, SocketFlags.None, sendResult =>
                                                                                              {
                                                                                                  socket.EndSend(sendResult);
                                                                                                  socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, callback, null);
                                                                                              }, null);
                               }

                           };


            socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, callback, null);
        }

        private class State
        {
            public Socket Socket { get; private set; }
            public byte[] Bytes { get; private set; }

            public State(Socket socket, byte[] bytes)
            {
                this.Socket = socket;
                this.Bytes = bytes;
            }
        }
    }
}
posted @ 2009-07-03 11:06  非空  阅读(5026)  评论(0编辑  收藏  举报