博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# Socket系列二 简单的创建 socket 通信
阅读量:6382 次
发布时间:2019-06-23

本文共 7609 字,大约阅读时间需要 25 分钟。

看了系列一 我们开启了对socket tcp的监听状态,那么这一章我们来讲解怎么创建socket的通信代码

我新建一个类 TSocketBase

 
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;        //接受空消息次数        private byte ZeroCount = 0;        public abstract void Receive(byte[] rbuff);        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];        }        ///         /// 关闭并释放资源        ///         ///         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)                {                }            }        }        ///         /// 递归接收消息方法        ///         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("链接已经被关闭");            }        }        ///         /// 接收消息回调函数        ///         ///         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);                            this.Receive(rbuff);                            //重置连续收到空字节数                            ZeroCount = 0;                            //继续开始异步接受消息                            ReceiveAsync();                        }                        else                        {                            ZeroCount++;                            if (ZeroCount == 5)                            {                                this.Close("错误链接");                            }                        }                    }                }                catch (System.Net.Sockets.SocketException)                {                    this.Close("链接已经被关闭");                }                catch (System.ObjectDisposedException)                {                    this.Close("链接已经被关闭");                }            }        }        ///         /// 错误判断        ///         ///         /// 
private 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; } /// /// 发送消息方法 /// 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; } }

  

 

上面我们事先了socket的异步接受消息,和同步发送消息已经关闭释放资源代码

接受消息net底层提供的接受消息的方法有很多,为什么我们要选择上面所写的呢?那是为了兼容U3D,silverlight, wpf, wp, wf,等程序可执行,不在重复做相同工作。

现在我们来创建一个实现类 TSocketClient

public class TSocketClient : TSocketBase    {        ///         /// 是否是服务器端的资源        ///         private bool isServer = false;        ///         /// 客户端主动请求服务器        ///         ///         ///         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();        }        ///         /// 这个是服务器收到有效链接初始化        ///         ///         public TSocketClient(Socket socket)        {            isServer = true;            this._Socket = socket;            this.SetSocket();            this.ReceiveAsync();        }        ///         /// 收到消息后        ///         ///         public override void Receive(byte[] rbuff)        {            Console.WriteLine("Receive Msg:" + System.Text.UTF8Encoding.Default.GetString(rbuff));            if (isServer)            {                this.SendMsg(System.Text.UTF8Encoding.Default.GetBytes("Holle Client!"));            }        }    }

  

 

因为是测试示例,所以我把服务器和客户端实现类写成了,只是用来不同的构造函数来区分,是客户端还是服务器的标识

 

接下来我们测试一下代码

1   class Program 2     { 3         static void Main(string[] args) 4         { 5             TCPListener tcp = new TCPListener(); 6             TSocketClient client = new TSocketClient(); 7             client.SendMsg(System.Text.UTF8Encoding.Default.GetBytes("Holle Server!")); 8             Console.ReadLine(); 9         }10     }

 

运行结果看出,我们连接成功并且发送消息成功。

转载地址:http://azzha.baihongyu.com/

你可能感兴趣的文章
.bashrc和.bash_profile的区别
查看>>
让你的PHP程序真正的实现多线程(PHP多线程类)(转)
查看>>
search-a-2d-matrix——二维矩阵找数
查看>>
lua基础【三】唯一数据结构table表
查看>>
Web应用安全审计工具WATOBO
查看>>
CSS3_animation笔记
查看>>
Android Google 地图 API for Android
查看>>
从 Zero 到 Hero ,一文掌握 Python--转
查看>>
【软件下载】整理一些外国的工具软件下载到网盘方便国内使用
查看>>
idea项目左边栏只能看到文件看不到项目结构
查看>>
idea如何编译maven项目
查看>>
在centos7下安装svn
查看>>
删除软链接
查看>>
windows7下MSN如何最小化到任务栏
查看>>
HDU-3016 Man Down 线段树
查看>>
初步认识注册表(待续)
查看>>
只能输入数字的TextBox自定义控件
查看>>
自定义事件
查看>>
浮点数的二进制
查看>>
主库配置关于Dataguard Online redo log 和 Standby redo log
查看>>