WPF实现Socket异步通讯示例

作者:袖梨 2022-06-25

示例一

 代码如下 复制代码

 

public class SocketHelper
    {
        private IPAddress ip = null;
        private int port = 0;
        private Socket socket = null;
        private static ManualResetEvent connectDone = new ManualResetEvent(false);
        private static ManualResetEvent sendDone = new ManualResetEvent(false);
        private static ManualResetEvent receiveDone = new ManualResetEvent(false);
        public SocketHelper(IPAddress ip, int port)
        {
            this.ip = ip;
            this.port = port;
        }
        public void StartRun(string _filePath, string _fileName, string _sourceId, string _userId, string _bookId, long _timeStamp, string _type)
        {
            try
            {
                IPEndPoint remoteEP = new IPEndPoint(ip, port);
                Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
                connectDone.WaitOne();
                if (client.Connected)
                {
                    //client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 10000000);//5秒超时
                    long _contenLength = ContentLength(_filePath + ".zip");
                    string head = "Content-Length=" + _contenLength + ";filename=" + _fileName + ";sourceid=" + _sourceId + ";userid=" + _userId + ";bookid=" + _bookId + ";timestamp=" + _timeStamp + ";type=" + _type + ";rn";
                    Send(client, head);
                    sendDone.WaitOne();
                    Receive(client);
                    receiveDone.WaitOne();
                    SendFile(0, client, _filePath + ".zip");
                    receiveDone.Reset();
                    Receive(client);
                    receiveDone.WaitOne();
                    client.Shutdown(SocketShutdown.Both);
                    client.Close();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
        private void ConnectCallback(IAsyncResult ar)
        {
            try
            {
                Socket client = (Socket)ar.AsyncState;
                client.EndConnect(ar);
                connectDone.Set();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
        private void Receive(Socket client)
        {
            try
            {
                StateObject state = new StateObject();
                state.workSocket = client;
                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
        private void ReceiveCallback(IAsyncResult ar)
        {
            try
            {
                StateObject state = (StateObject)ar.AsyncState;
                Socket client = state.workSocket;
                int bytesRead = client.EndReceive(ar);
                if (bytesRead > 0)
                {
                    string aa = Encoding.UTF8.GetString(state.buffer, 0, bytesRead);
                    receiveDone.Set();
                }
                else
                {
                    // All the data has arrived; put it in response.    
                    if (state.sb.Length > 1)
                    {
                        //response = state.sb.ToString();
                    }
                    // Signal that all bytes have been received.    
                    receiveDone.Set();
                }
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("{0} 服务器连接中断", ex.Message));
            }
        }
        ///


        /// 文件流发送
        ///

        ///
        ///
        ///
        private void SendFile(long _offset, Socket _client, string _path)
        {
            using (FileStream stream = new FileStream(_path, FileMode.Open))
            {
                //文件指针指向0位置
                stream.Seek(_offset, SeekOrigin.Begin);
                NetworkStream netStream = new NetworkStream(_client);
                int length;
                byte[] buf = new byte[1024];
                while ((length = stream.Read(buf, 0, buf.Length)) > 0)
                {
                    netStream.Write(buf, 0, length);
                    netStream.Flush();
                }
            }
        }
        ///
        /// 获得资源包的大小
        ///

        ///
        ///
        private long ContentLength(string path)
        {
            long _contenLength = 0;
            using (FileStream stream = new FileStream(path, FileMode.Open))
            {
                _contenLength = stream.Length;
            }
            return _contenLength;
        }
        ///
        /// 协议头文件的发送
        ///

        ///
        ///
        private void Send(Socket client, String data)
        {
            byte[] byteData = Encoding.UTF8.GetBytes(data);
            client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client);
        }
        private void SendCallback(IAsyncResult ar)
        {
            try
            {
                Socket client = (Socket)ar.AsyncState;
                int bytesSent = client.EndSend(ar);
                sendDone.Set();
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("{0} 发送回调失败", ex.Message));
            }
        }
    }


 

三种方式实现异步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 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;
            }
        }
    }
}

相关文章

精彩推荐