服务器、客户端实例(C#)

来源:互联网 发布:淘宝生意参谋标准版 编辑:程序博客网 时间:2024/03/29 15:07

Socket基类:

using System;using System.Net.Sockets;public abstract class TSocketBase{    //封装socket    internal Socket _Socket;    //回调    private AsyncCallback aCallback;    //接受数据的缓冲区    private byte[] Buffers;    //标识是否已经释放    private volatile bool IsDispose;    //10K的缓冲区空间    private int BufferSize = 10 * 1024;    //收取消息状态码    private SocketError ReceiveError;    //发送消息的状态码    private SocketError SenderError;    //每一次接受到的字节数    private int ReceiveSize = 0;    //接受空消息次数    byte ZeroCount = 0;    public abstract void Receive(TSocketMessage msg);    public void SetSocket()    {        this.aCallback = new AsyncCallback(this.ReceiveCallback);        this.IsDispose = false;        this._Socket.ReceiveBufferSize = this.BufferSize;        this._Socket.SendBufferSize = this.BufferSize;        this.Buffers = new byte[this.BufferSize];    }    /// <summary>    /// 关闭并释放资源    /// </summary>    /// <param name="msg"></param>    public void Close(string msg)    {        if (!this.IsDispose)        {            this.IsDispose = true;            try            {                try { this._Socket.Close(); }                catch { }                IDisposable disposable = this._Socket;                if (disposable != null) { disposable.Dispose(); }                this.Buffers = null;                GC.SuppressFinalize(this);            }            catch (Exception) { }        }    }    /// <summary>    /// 递归接收消息方法    /// </summary>    internal void ReceiveAsync()    {        try        {            if (!this.IsDispose && this._Socket.Connected)            {                this._Socket.BeginReceive(this.Buffers, 0, this.BufferSize, SocketFlags.None, out SenderError, this.aCallback, this);                CheckSocketError(ReceiveError);            }        }        catch (System.Net.Sockets.SocketException) { this.Close("链接已经被关闭"); }        catch (System.ObjectDisposedException) { this.Close("链接已经被关闭"); }    }    /// <summary>    /// 消息解析器    /// </summary>    public MarshalEndian mersha = new MarshalEndian();    /// <summary>    /// 接收消息回调函数    /// </summary>    /// <param name="iar"></param>    private void ReceiveCallback(IAsyncResult iar)    {        if (!this.IsDispose)        {            try            {                //接受消息                ReceiveSize = _Socket.EndReceive(iar, out ReceiveError);                //检查状态码                if (!CheckSocketError(ReceiveError) && SocketError.Success == ReceiveError)                {                    //判断接受的字节数                    if (ReceiveSize > 0)                    {                        byte[] rbuff = new byte[ReceiveSize];                        Array.Copy(this.Buffers, rbuff, ReceiveSize);                        var msgs = mersha.GetDcAppMess(rbuff, ReceiveSize);                        foreach (var msg in msgs)                        {                            this.Receive(msg);                        }                        //重置连续收到空字节数                        ZeroCount = 0;                        //继续开始异步接受消息                        ReceiveAsync();                    }                    else                    {                        ZeroCount++;                        if (ZeroCount == 5) { this.Close("错误链接"); }                    }                }            }            catch (System.Net.Sockets.SocketException) { this.Close("链接已经被关闭"); }            catch (System.ObjectDisposedException) { this.Close("链接已经被关闭"); }        }    }    /// <summary>    /// 错误判断    /// </summary>    /// <param name="socketError"></param>    /// <returns></returns>    bool CheckSocketError(SocketError socketError)    {        switch ((socketError))        {            case SocketError.SocketError:            case SocketError.VersionNotSupported:            case SocketError.TryAgain:            case SocketError.ProtocolFamilyNotSupported:            case SocketError.ConnectionAborted:            case SocketError.ConnectionRefused:            case SocketError.ConnectionReset:            case SocketError.Disconnecting:            case SocketError.HostDown:            case SocketError.HostNotFound:            case SocketError.HostUnreachable:            case SocketError.NetworkDown:            case SocketError.NetworkReset:            case SocketError.NetworkUnreachable:            case SocketError.NoData:            case SocketError.OperationAborted:            case SocketError.Shutdown:            case SocketError.SystemNotReady:            case SocketError.TooManyOpenSockets:                this.Close(socketError.ToString());                return true;        }        return false;    }    /// <summary>    /// 发送消息方法    /// </summary>    internal int SendMsg(byte[] buffer)    {        int size = 0;        try        {            if (!this.IsDispose)            {                size = this._Socket.Send(buffer, 0, buffer.Length, SocketFlags.None, out SenderError);                CheckSocketError(SenderError);            }        }        catch (System.ObjectDisposedException) { this.Close("链接已经被关闭"); }        catch (System.Net.Sockets.SocketException) { this.Close("链接已经被关闭"); }        buffer = null;        return size;    }    internal int SendMsg(TSocketMessage tdata)    {        byte[] buffer = mersha.Encode(tdata);        return SendMsg(buffer);    }}

Socket客户端 继承基类:

using System;using System.Net.Sockets;using System.Text;public class TSocketClient : TSocketBase{    /// <summary>    /// 是否是服务器端的资源    /// </summary>    bool isServer = false;    /// <summary>    /// 客户端主动请求服务器    /// </summary>    /// <param name="ip"></param>    /// <param name="port"></param>    public TSocketClient(string ip = "127.0.0.1", int port = 9527)    {        isServer = false;        this._Socket = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);        this._Socket.Connect(ip, port);        this.SetSocket();        this.ReceiveAsync();    }    /// <summary>    /// 这个是服务器收到有效链接初始化    /// </summary>    /// <param name="socket"></param>    public TSocketClient(Socket socket)    {        isServer = true;        this._Socket = socket;        this.SetSocket();        this.ReceiveAsync();    }    /// <summary>    /// 收到消息后    /// </summary>    /// <param name="rbuff"></param>    public override void Receive(TSocketMessage msg)    {        Console.WriteLine("Receive ID:" + msg.MsgID + " Msg:" + System.Text.UTF8Encoding.Default.GetString(msg.MsgBuffer));        if (isServer)        {            this.SendMsg(new TSocketMessage(msg.MsgID, Encoding.Default.GetBytes("Holle Client!")));        }    }}

Tcp监听类(服务端):

using System;using System.Collections.Generic;using System.Net;using System.Net.Sockets;using System.Runtime.InteropServices;/// <summary>/// 建立TCP通信监听服务/// </summary>internal class TCPListener{    private IPEndPoint _IP;    private Socket _Listeners;    private volatile bool IsInit = false;    List<TSocketBase> sockets = new List<TSocketBase>();    /// <summary>    /// 初始化服务器    /// </summary>    public TCPListener(string ip = "0.0.0.0", int port = 9527)    {        IsInit = true;        IPEndPoint localEP = new IPEndPoint(IPAddress.Parse(ip), port);        this._IP = localEP;        try        {            Console.WriteLine(string.Format("Listen Tcp -> {0}:{1} ", ip, port));            this._Listeners = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);            this._Listeners.Bind(this._IP);            this._Listeners.Listen(5000);            SocketAsyncEventArgs sea = new SocketAsyncEventArgs();            sea.Completed += new EventHandler<SocketAsyncEventArgs>(this.AcceptAsync_Async);            this.AcceptAsync(sea);        }        catch (Exception ex)        {            Console.WriteLine(ex);            this.Dispose();        }    }    private void AcceptAsync(SocketAsyncEventArgs sae)    {        if (IsInit)        {            if (!this._Listeners.AcceptAsync(sae))            {                AcceptAsync_Async(this, sae);            }        }        else        {            if (sae != null)            {                sae.Dispose();            }        }    }    private void AcceptAsync_Async(object sender, SocketAsyncEventArgs sae)    {        if (sae.SocketError == SocketError.Success)        {            var socket = new TSocketClient(sae.AcceptSocket);            sockets.Add(socket);            Console.WriteLine("Remote Socket LocalEndPoint:" + sae.AcceptSocket.LocalEndPoint + " RemoteEndPoint:" + sae.AcceptSocket.RemoteEndPoint.ToString());        }        sae.AcceptSocket = null;        if (IsInit)        {            this._Listeners.AcceptAsync(sae);        }        else { sae.Dispose(); }    }    /// <summary>    /// 释放资源    /// </summary>    public void Dispose()    {        if (IsInit)        {            IsInit = false;            this.Dispose(true);            GC.SuppressFinalize(this);        }    }    /// <summary>    /// 释放所占用的资源    /// </summary>    /// <param name="flag1"></param>    protected virtual void Dispose([MarshalAs(UnmanagedType.U1)] bool flag1)    {        if (flag1)        {            if (_Listeners != null)            {                try                {                    Console.WriteLine(string.Format("Stop Listener Tcp -> {0}:{1} ", this.IP.Address.ToString(), this.IP.Port));                    _Listeners.Close();                    _Listeners.Dispose();                }                catch { }            }        }    }    /// <summary>    /// 获取绑定终结点    /// </summary>    public IPEndPoint IP { get { return this._IP; } }}

测试类:

using System;class Program{    static void Main(string[] args)    {        MarshalEndian mersha = new MarshalEndian();//拆包解析类        TCPListener tcp = new TCPListener();        TSocketClient client = new TSocketClient();        for (int i = 1; i < 5; i++)        {            client.SendMsg(new TSocketMessage(i, System.Text.UTF8Encoding.Default.GetBytes("Holle Server!")));        }        Console.ReadLine();    }}
封装、解析包体请参考之前的文章。




















0 0
原创粉丝点击