C# 处理TCP数据的类(服务端)
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 }