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 /,如需转载请自行联系原作者
目录
打赏
0
0
0
0
19
分享
相关文章
|
9月前
|
C# 一分钟浅谈:Socket 编程基础
【10月更文挑战第7天】本文介绍了Socket编程的基础知识、基本操作及常见问题,通过C#代码示例详细展示了服务器端和客户端的Socket通信过程,包括创建、绑定、监听、连接、数据收发及关闭等步骤,帮助开发者掌握Socket编程的核心技术和注意事项。
230 3
C# 一分钟浅谈:Socket 编程基础
Socket如何实现客户端和服务器间的通信
通过上述示例,展示了如何使用Python的Socket模块实现基本的客户端和服务器间的通信。Socket提供了一种简单且强大的方式来建立和管理网络连接,适用于各种网络编程应用。理解和掌握Socket编程,可以帮助开发者构建高效、稳定的网络应用程序。
170 10
# 2个类轻松构建高效Socket通信库
本文介绍了一种通过两个类`EpollEventHandler`和`IEpollEvent`构建高效Socket通信库的方法。该库支持TCP、UDP和Unix域套接字,采用I/O多路复用技术(如epoll),提升并发处理能力。通过抽象基类和具体事件类的设计,简化了API使用,便于开发者快速上手。文章还提供了服务端与客户端的实例代码,展示其在实际项目中的应用效果。此Socket库适应嵌入式环境,功能定制性强,有助于减少外部依赖并提升维护效率。
125 76
# 2个类轻松构建高效Socket通信库
|
11月前
|
python socket 简单通信
python socket 简单通信
145 1
C#中简单Socket编程
1. 先运行服务器代码。服务器将开始监听指定的IP和端口,等待客户端连接。 1. 然后运行客户端代码。客户端将连接到服务器并发送消息。 1. 服务器接收到消息后,将回应客户端,并在控制台上显示接收到的消息。 1. 客户端接收到服务器的回应消息,并在控制台上显示。
307 15
C#使用Socket实现分布式事件总线,不依赖第三方MQ
`CodeWF.EventBus.Socket` 是一个轻量级的、基于Socket的分布式事件总线系统,旨在简化分布式架构中的事件通信。它允许进程之间通过发布/订阅模式进行通信,无需依赖外部消息队列服务。
C#使用Socket实现分布式事件总线,不依赖第三方MQ
Socket通信之网络协议基本原理
【10月更文挑战第10天】网络协议定义了机器间通信的标准格式,确保信息准确无损地传输。主要分为两种模型:OSI七层模型与TCP/IP模型。
Socket通信之网络协议基本原理
【9月更文挑战第14天】网络协议是机器间交流的约定格式,确保信息准确传达。主要模型有OSI七层与TCP/IP模型,通过分层简化复杂网络环境。IP地址全局定位设备,MAC地址则在本地网络中定位。网络分层后,数据包层层封装,经由不同层次协议处理,最终通过Socket系统调用在应用层解析和响应。
看看如何使用 C# 代码让 MQTT 进行完美通信
看看如何使用 C# 代码让 MQTT 进行完美通信
1148 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问