1 using System;
2 using System.Collections.Generic;
3 using System.Net;
4 using System.Net.Sockets;
5 using System.Threading;
6
7 namespace TestDemo
8 {
9 /// <summary>
10 /// 处理TCP数据的类(服务端)
11 /// </summary>
12 public class TcpService
13 {
14 /// <summary>
15 /// TCP监听对象
16 /// </summary>
17 private TcpListener tcpListener;
18
19 /// <summary>
20 /// 创建TCP监听
21 /// </summary>
22 public void CreateListener(int port)
23 {
24 // 监听对象
25 tcpListener = new TcpListener(IPAddress.Any, port);
26 tcpListener.Start();
27 // 独立线程监听
28 Thread thread = new Thread(StartListener);
29 thread.Start();
30 }
31
32 /// <summary>
33 /// 开始监听
34 /// </summary>
35 private void StartListener()
36 {
37 while (true)
38 {
39 try
40 {
41 // TCP监听
42 TcpClient tcpClient = tcpListener.AcceptTcpClient();
43 // 多线程处理数据
44 Thread thread = new Thread(new ParameterizedThreadStart(delegate { DealTcpData(tcpClient); }));
45 thread.Start();
46 }
47 catch (Exception ex)
48 {
49 // 错误日志
50 Log.WriteError(ex);
51 }
52 }
53 }
54
55 /// <summary>
56 /// 处理TCP数据
57 /// <para>lv结构:数据的前4个字节(int),记录了数据区的长度</para>
58 /// <para>注意:数据结构根据实际使用情况而定</para>
59 /// </summary>
60 private void DealTcpData(TcpClient tcpClient)
61 {
62 try
63 {
64 if (tcpClient.Connected)
65 {
66 // 取得流
67 NetworkStream networkStream = tcpClient.GetStream();
68 networkStream.ReadTimeout = 500;
69 networkStream.WriteTimeout = 500;
70 #region 接收数据
71 // 接收数据储存
72 List<byte> list = new List<byte>();
73 // 数据区总长度
74 byte[] lenArr = new byte[4];
75 networkStream.Read(lenArr, 0, lenArr.Length);
76 int dataLen = BitConverter.ToInt32(lenArr, 0);
77 // 读取数据区数据
78 int total = 0;
79 // 每次读取的数据大小
80 int arrLen = 1024;
81 while (true)
82 {
83 // 读取数据
84 byte[] arr = new byte[arrLen];
85 int len = networkStream.Read(arr, 0, arr.Length);
86 for (int i = 0; i < len; i++)
87 {
88 list.Add(arr[i]);
89 }
90 // 判断数据的是否读取完成
91 total += len;
92 if (dataLen - total <= 0)
93 {
94 break;
95 }
96 if (dataLen - total < arrLen)
97 {
98 arrLen = dataLen - total;
99 }
100 Thread.Sleep(0);
101 }
102 // 根据功能或实际情况处理接收的数据
103 byte[] receiveData = list.ToArray();
104 #endregion
105 #region 发送数据
106 // 取得数据
107 // 根据功能或实际情况做成需要发送的数据
108 byte[] dataArr = new byte[] { 0x01, 0x02, 0x03, 0x04 }; // 测试数据
109 if (dataArr != null)
110 {
111 // 数据长度
112 byte[] lengArr = BitConverter.GetBytes(dataArr.Length);
113 // 拼接数据头(lv结构)
114 byte[] sendArr = new byte[lengArr.Length + dataArr.Length];
115 lengArr.CopyTo(sendArr, 0);
116 dataArr.CopyTo(sendArr, 4);
117 // 发送数据
118 try
119 {
120 lock (networkStream)
121 {
122 networkStream.Write(sendArr, 0, sendArr.Length);
123 }
124 }
125 catch { }
126 }
127 #endregion
128 }
129 }
130 catch (Exception ex)
131 {
132 // 错误日志
133 Log.WriteError(ex);
134 }
135 finally
136 {
137 // 判断TCP对象是否连接
138 if (tcpClient != null)
139 {
140 JudgeTcpConnection(tcpClient);
141 }
142 }
143 }
144
145 /// <summary>
146 /// 判断TCP对象是否连接
147 /// </summary>
148 private void JudgeTcpConnection(TcpClient tcpClient, int timeout = 3)
149 {
150 try
151 {
152 DateTime time = DateTime.Now;
153 while (true)
154 {
155 // 超时时间判断
156 if (time.AddSeconds(timeout) < DateTime.Now)
157 {
158 break;
159 }
160 // 连接状态判断
161 if (!tcpClient.Connected)
162 {
163 break;
164 }
165 else
166 {
167 bool flag = tcpClient.Client.Poll(1000, SelectMode.SelectRead);
168 if (flag)
169 {
170 break;
171 }
172 }
173 Thread.Sleep(0);
174 }
175 }
176 catch (Exception ex)
177 {
178 // 错误日志
179 Log.WriteError(ex);
180 }
181 finally
182 {
183 // 关闭连接
184 tcpClient.Close();
185 }
186 }
187 }
188 }