看了系列一 我們開啟了對socket tcp的監聽狀态,那麼這一章我們來講解怎麼建立socket的通信代碼
我建立一個類 TSocketBase
<a href="http://www.cnblogs.com/soundcode/p/7238616.html#">?</a>
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
<code>public</code> <code>abstract</code> <code>class</code> <code>TSocketBase</code>
<code> </code><code>{</code>
<code> </code><code>//封裝socket</code>
<code> </code><code>internal</code> <code>Socket _Socket;</code>
<code> </code><code>//回調</code>
<code> </code><code>private</code> <code>AsyncCallback aCallback;</code>
<code> </code><code>//接受資料的緩沖區</code>
<code> </code><code>private</code> <code>byte</code><code>[] Buffers;</code>
<code> </code><code>//辨別是否已經釋放</code>
<code> </code><code>private</code> <code>volatile</code> <code>bool</code> <code>IsDispose;</code>
<code> </code><code>//10K的緩沖區空間</code>
<code> </code><code>private</code> <code>int</code> <code>BufferSize = 10*1024;</code>
<code> </code><code>//收取消息狀态碼</code>
<code> </code><code>private</code> <code>SocketError ReceiveError;</code>
<code> </code><code>//發送消息的狀态碼</code>
<code> </code><code>private</code> <code>SocketError SenderError;</code>
<code> </code><code>//每一次接受到的位元組數</code>
<code> </code><code>private</code> <code>int</code> <code>ReceiveSize = 0;</code>
<code> </code><code>//接受空消息次數</code>
<code> </code><code>private</code> <code>byte</code> <code>ZeroCount = 0;</code>
<code> </code><code>public</code> <code>abstract</code> <code>void</code> <code>Receive(</code><code>byte</code><code>[] rbuff);</code>
<code> </code><code>public</code> <code>void</code> <code>SetSocket()</code>
<code> </code><code>{</code>
<code> </code><code>this</code><code>.aCallback =</code><code>new</code> <code>AsyncCallback(</code><code>this</code><code>.ReceiveCallback);</code>
<code> </code><code>this</code><code>.IsDispose =</code><code>false</code><code>;</code>
<code> </code><code>this</code><code>._Socket.ReceiveBufferSize =</code><code>this</code><code>.BufferSize;</code>
<code> </code><code>this</code><code>._Socket.SendBufferSize =</code><code>this</code><code>.BufferSize;</code>
<code> </code><code>this</code><code>.Buffers =</code><code>new</code> <code>byte</code><code>[</code><code>this</code><code>.BufferSize];</code>
<code> </code><code>}</code>
<code> </code><code>/// <summary></code>
<code> </code><code>/// 關閉并釋放資源</code>
<code> </code><code>/// </summary></code>
<code> </code><code>/// <param name="msg"></param></code>
<code> </code><code>public</code> <code>void</code> <code>Close(</code><code>string</code> <code>msg)</code>
<code> </code><code>if</code> <code>(!</code><code>this</code><code>.IsDispose)</code>
<code> </code><code>{</code>
<code> </code><code>this</code><code>.IsDispose =</code><code>true</code><code>;</code>
<code> </code><code>try</code>
<code> </code><code>{</code>
<code> </code><code>try</code>
<code> </code><code>{</code>
<code> </code><code>this</code><code>._Socket.Close();</code>
<code> </code><code>}</code>
<code> </code><code>catch</code>
<code> </code><code>IDisposable disposable =</code><code>this</code><code>._Socket;</code>
<code> </code><code>if</code> <code>(disposable !=</code><code>null</code><code>)</code>
<code> </code><code>disposable.Dispose();</code>
<code> </code><code>this</code><code>.Buffers =</code><code>null</code><code>;</code>
<code> </code><code>GC.SuppressFinalize(</code><code>this</code><code>);</code>
<code> </code><code>}</code>
<code> </code><code>catch</code> <code>(Exception)</code>
<code> </code><code>}</code>
<code> </code><code>/// 遞歸接收消息方法</code>
<code> </code><code>internal</code> <code>void</code> <code>ReceiveAsync()</code>
<code> </code><code>try</code>
<code> </code><code>if</code> <code>(!</code><code>this</code><code>.IsDispose &&</code><code>this</code><code>._Socket.Connected)</code>
<code> </code><code>this</code><code>._Socket.BeginReceive(</code><code>this</code><code>.Buffers, 0,</code><code>this</code><code>.BufferSize, SocketFlags.None,</code><code>out</code> <code>SenderError,</code>
<code> </code><code>this</code><code>.aCallback,</code><code>this</code><code>);</code>
<code> </code><code>CheckSocketError(ReceiveError);</code>
<code> </code><code>catch</code> <code>(System.Net.Sockets.SocketException)</code>
<code> </code><code>this</code><code>.Close(</code><code>"連結已經被關閉"</code><code>);</code>
<code> </code><code>catch</code> <code>(System.ObjectDisposedException)</code>
<code> </code><code>/// 接收消息回調函數</code>
<code> </code><code>/// <param name="iar"></param></code>
<code> </code><code>private</code> <code>void</code> <code>ReceiveCallback(IAsyncResult iar)</code>
<code> </code><code>//接受消息</code>
<code> </code><code>ReceiveSize = _Socket.EndReceive(iar,</code><code>out</code> <code>ReceiveError);</code>
<code> </code><code>//檢查狀态碼</code>
<code> </code><code>if</code> <code>(!CheckSocketError(ReceiveError) && SocketError.Success == ReceiveError)</code>
<code> </code><code>//判斷接受的位元組數</code>
<code> </code><code>if</code> <code>(ReceiveSize > 0)</code>
<code> </code><code>{</code>
<code> </code><code>byte</code><code>[] rbuff =</code><code>new</code> <code>byte</code><code>[ReceiveSize];</code>
<code> </code><code>Array.Copy(</code><code>this</code><code>.Buffers, rbuff, ReceiveSize);</code>
<code> </code><code>this</code><code>.Receive(rbuff);</code>
<code> </code><code>//重置連續收到空位元組數</code>
<code> </code><code>ZeroCount = 0;</code>
<code> </code><code>//繼續開始異步接受消息</code>
<code> </code><code>ReceiveAsync();</code>
<code> </code><code>}</code>
<code> </code><code>else</code>
<code> </code><code>ZeroCount++;</code>
<code> </code><code>if</code> <code>(ZeroCount == 5)</code>
<code> </code><code>{</code>
<code> </code><code>this</code><code>.Close(</code><code>"錯誤連結"</code><code>);</code>
<code> </code><code>}</code>
<code> </code><code>catch</code> <code>(System.Net.Sockets.SocketException)</code>
<code> </code><code>this</code><code>.Close(</code><code>"連結已經被關閉"</code><code>);</code>
<code> </code><code>catch</code> <code>(System.ObjectDisposedException)</code>
<code> </code><code>/// 錯誤判斷</code>
<code> </code><code>/// <param name="socketError"></param></code>
<code> </code><code>/// <returns></returns></code>
<code> </code><code>private</code> <code>bool</code> <code>CheckSocketError(SocketError socketError)</code>
<code> </code><code>switch</code> <code>((socketError))</code>
<code> </code><code>case</code> <code>SocketError.SocketError:</code>
<code> </code><code>case</code> <code>SocketError.VersionNotSupported:</code>
<code> </code><code>case</code> <code>SocketError.TryAgain:</code>
<code> </code><code>case</code> <code>SocketError.ProtocolFamilyNotSupported:</code>
<code> </code><code>case</code> <code>SocketError.ConnectionAborted:</code>
<code> </code><code>case</code> <code>SocketError.ConnectionRefused:</code>
<code> </code><code>case</code> <code>SocketError.ConnectionReset:</code>
<code> </code><code>case</code> <code>SocketError.Disconnecting:</code>
<code> </code><code>case</code> <code>SocketError.HostDown:</code>
<code> </code><code>case</code> <code>SocketError.HostNotFound:</code>
<code> </code><code>case</code> <code>SocketError.HostUnreachable:</code>
<code> </code><code>case</code> <code>SocketError.NetworkDown:</code>
<code> </code><code>case</code> <code>SocketError.NetworkReset:</code>
<code> </code><code>case</code> <code>SocketError.NetworkUnreachable:</code>
<code> </code><code>case</code> <code>SocketError.NoData:</code>
<code> </code><code>case</code> <code>SocketError.OperationAborted:</code>
<code> </code><code>case</code> <code>SocketError.Shutdown:</code>
<code> </code><code>case</code> <code>SocketError.SystemNotReady:</code>
<code> </code><code>case</code> <code>SocketError.TooManyOpenSockets:</code>
<code> </code><code>this</code><code>.Close(socketError.ToString());</code>
<code> </code><code>return</code> <code>true</code><code>;</code>
<code> </code><code>return</code> <code>false</code><code>;</code>
<code> </code><code>/// 發送消息方法</code>
<code> </code><code>internal</code> <code>int</code> <code>SendMsg(</code><code>byte</code><code>[] buffer)</code>
<code> </code><code>int</code> <code>size = 0;</code>
<code> </code><code>if</code> <code>(!</code><code>this</code><code>.IsDispose)</code>
<code> </code><code>size =</code><code>this</code><code>._Socket.Send(buffer, 0, buffer.Length, SocketFlags.None,</code><code>out</code> <code>SenderError);</code>
<code> </code><code>CheckSocketError(SenderError);</code>
<code> </code><code>buffer =</code><code>null</code><code>;</code>
<code> </code><code>return</code> <code>size;</code>
<code> </code><code>}</code>
上面我們事先了socket的異步接受消息,和同步發送消息已經關閉釋放資源代碼
接受消息net底層提供的接受消息的方法有很多,為什麼我們要選擇上面所寫的呢?那是為了相容U3D,silverlight, wpf, wp, wf,等程式可執行,不在重複做相同工作。
現在我們來建立一個實作類 TSocketClient
<code>public</code> <code>class</code> <code>TSocketClient : TSocketBase</code>
<code> </code><code>/// 是否是伺服器端的資源</code>
<code> </code><code>private</code> <code>bool</code> <code>isServer =</code><code>false</code><code>;</code>
<code> </code><code>/// 用戶端主動請求伺服器</code>
<code> </code><code>/// <param name="ip"></param></code>
<code> </code><code>/// <param name="port"></param></code>
<code> </code><code>public</code> <code>TSocketClient(</code><code>string</code> <code>ip =</code><code>"127.0.0.1"</code><code>,</code><code>int</code> <code>port = 9527)</code>
<code> </code><code>isServer =</code><code>false</code><code>;</code>
<code> </code><code>this</code><code>._Socket =</code><code>new</code> <code>System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);</code>
<code> </code><code>this</code><code>._Socket.Connect(ip, port);</code>
<code> </code><code>this</code><code>.SetSocket();</code>
<code> </code><code>this</code><code>.ReceiveAsync();</code>
<code> </code><code>/// 這個是伺服器收到有效連結初始化</code>
<code> </code><code>/// <param name="socket"></param></code>
<code> </code><code>public</code> <code>TSocketClient(Socket socket)</code>
<code> </code><code>isServer =</code><code>true</code><code>;</code>
<code> </code><code>this</code><code>._Socket = socket;</code>
<code> </code><code>/// 收到消息後</code>
<code> </code><code>/// <param name="rbuff"></param></code>
<code> </code><code>public</code> <code>override</code> <code>void</code> <code>Receive(</code><code>byte</code><code>[] rbuff)</code>
<code> </code><code>Console.WriteLine(</code><code>"Receive Msg:"</code> <code>+ System.Text.UTF8Encoding.Default.GetString(rbuff));</code>
<code> </code><code>if</code> <code>(isServer)</code>
<code> </code><code>this</code><code>.SendMsg(System.Text.UTF8Encoding.Default.GetBytes(</code><code>"Holle Client!"</code><code>));</code>
因為是測試示例,是以我把伺服器和用戶端實作類寫成了,隻是用來不同的構造函數來區分,是用戶端還是伺服器的辨別
接下來我們測試一下代碼


運作結果看出,我們連接配接成功并且發送消息成功。