C# Socket系列二 简单的创建 socket 通信

简介:

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

我新建一个类 TSocketBase

 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
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];
         }
 
 
         /// <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>
         /// <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);
                             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( "链接已经被关闭" );
                 }
             }
         }
 
         /// <summary>
         /// 错误判断
         /// </summary>
         /// <param name="socketError"></param>
         /// <returns></returns>
         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 ;
         }
 
         /// <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;
         }
     }

  

 

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public class TSocketClient : TSocketBase
     {
         /// <summary>
         /// 是否是服务器端的资源
         /// </summary>
         private 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( 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://www.cnblogs.com/soundcode/p/7238616.html /,如需转载请自行联系原作者
相关文章
|
2月前
|
C# 开发者
C# 一分钟浅谈:Socket 编程基础
【10月更文挑战第7天】本文介绍了Socket编程的基础知识、基本操作及常见问题,通过C#代码示例详细展示了服务器端和客户端的Socket通信过程,包括创建、绑定、监听、连接、数据收发及关闭等步骤,帮助开发者掌握Socket编程的核心技术和注意事项。
102 3
C# 一分钟浅谈:Socket 编程基础
|
4月前
|
Python
python socket 简单通信
python socket 简单通信
46 1
|
4月前
|
网络协议 安全 网络安全
网络编程:基于socket的TCP/IP通信。
网络编程:基于socket的TCP/IP通信。
264 0
|
2月前
|
消息中间件 网络协议 C#
C#使用Socket实现分布式事件总线,不依赖第三方MQ
`CodeWF.EventBus.Socket` 是一个轻量级的、基于Socket的分布式事件总线系统,旨在简化分布式架构中的事件通信。它允许进程之间通过发布/订阅模式进行通信,无需依赖外部消息队列服务。
C#使用Socket实现分布式事件总线,不依赖第三方MQ
|
6月前
|
Java 数据挖掘 开发者
Java网络编程进阶:Socket通信的高级特性与应用
【6月更文挑战第21天】Java Socket通信是分布式应用的基础,涉及高级特性如多路复用(Selector)和零拷贝,提升效率与响应速度。结合NIO和AIO,适用于高并发场景如游戏服务器和实时数据分析。示例展示了基于NIO的多路复用服务器实现。随着技术发展,WebSockets、HTTP/2、QUIC等新协议正变革网络通信,掌握Socket高级特性为应对未来挑战准备。
56 1
|
2月前
|
网络协议 Linux 应用服务中间件
Socket通信之网络协议基本原理
【10月更文挑战第10天】网络协议定义了机器间通信的标准格式,确保信息准确无损地传输。主要分为两种模型:OSI七层模型与TCP/IP模型。
|
6月前
|
Java
Java Socket编程与多线程:提升客户端-服务器通信的并发性能
【6月更文挑战第21天】Java网络编程中,Socket结合多线程提升并发性能,服务器对每个客户端连接启动新线程处理,如示例所示,实现每个客户端的独立操作。多线程利用多核处理器能力,避免串行等待,提升响应速度。防止死锁需减少共享资源,统一锁定顺序,使用超时和重试策略。使用synchronized、ReentrantLock等维持数据一致性。多线程带来性能提升的同时,也伴随复杂性和挑战。
107 0
|
6月前
|
安全 Java 网络安全
Java Socket编程教程:构建安全可靠的客户端-服务器通信
【6月更文挑战第21天】构建安全的Java Socket通信涉及SSL/TLS加密、异常处理和重连策略。示例中,`SecureServer`使用SSLServerSocketFactory创建加密连接,而`ReliableClient`展示异常捕获与自动重连。理解安全意识,如防数据截获和中间人攻击,是首要步骤。通过良好的编程实践,确保网络应用在复杂环境中稳定且安全。
109 0
|
3月前
|
网络协议 Linux 应用服务中间件
Socket通信之网络协议基本原理
【9月更文挑战第14天】网络协议是机器间交流的约定格式,确保信息准确传达。主要模型有OSI七层与TCP/IP模型,通过分层简化复杂网络环境。IP地址全局定位设备,MAC地址则在本地网络中定位。网络分层后,数据包层层封装,经由不同层次协议处理,最终通过Socket系统调用在应用层解析和响应。
|
4月前
|
物联网 C# Windows
看看如何使用 C# 代码让 MQTT 进行完美通信
看看如何使用 C# 代码让 MQTT 进行完美通信
626 0