Table of Contents
Introduction to this article
TcpListener synchronizes TCP server
Home Backend Development C#.Net Tutorial C# network programming series of articles (4) TcpListener realizes synchronization of TCP server

C# network programming series of articles (4) TcpListener realizes synchronization of TCP server

Feb 27, 2017 am 11:19 AM

Introduction to this article

The TcpListener class provides some simple methods for listening and accepting incoming connection requests in blocking synchronization mode. TcpListener can be connected using TcpClient or Socket. A TcpListener can be created using an IPEndPoint, a local IP address and a port number, or just a port number. You can specify the local IP address as Any and the local port number as 0 if you want the underlying service provider to assign these values ​​for you. If you choose to do this, you can use the LocalEndpoint property to identify the specified information after connecting to the socket. Use the Start method to start listening for incoming connection requests. Start will queue incoming connections until you call the Stop method or it has finished queuing MaxConnections. You can use AcceptSocket or AcceptTcpClient to extract connections from the queue of incoming connection requests. Both methods will block. If you want to avoid blocking, first use the Pending method to determine whether there are available connection requests in the queue.
Although TcpListener has been encapsulated relatively well, we use it to construct a relatively good synchronous TCP server. Here is still the same as the previous two chapters. The code in the server is given. The comments in the code are very detailed. I also Relevant encapsulation classes will be given.

TcpListener synchronizes TCP server

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

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Net.Sockets;

using System.Net;

using System.Threading;

 

namespace NetFrame.Net.TCP.Listener.Synchronous

{

    /// <summary>

    /// TcpListener实现同步TCP服务器

    /// </summary>

    public class TCPServer

    {

        #region Fields

        /// <summary>

        /// 服务器程序允许的最大客户端连接数

        /// </summary>

        private int _maxClient;

 

        /// <summary>

        /// 当前的连接的客户端数

        /// </summary>

        private int _clientCount;

 

        /// <summary>

        /// 服务器使用的异步TcpListener

        /// </summary>

        private TcpListener _listener;

 

        /// <summary>

        /// 客户端会话列表

        /// </summary>

        private List<TCPClientHandle> _clients;

 

        private bool disposed = false;

 

        #endregion

 

        #region Properties

 

        /// <summary>

        /// 服务器是否正在运行

        /// </summary>

        public bool IsRunning { get; private set; }

        /// <summary>

        /// 监听的IP地址

        /// </summary>

        public IPAddress Address { get; private set; }

        /// <summary>

        /// 监听的端口

        /// </summary>

        public int Port { get; private set; }

        /// <summary>

        /// 通信使用的编码

        /// </summary>

        public Encoding Encoding { get; set; }

 

        #endregion

 

        #region 构造器

        /// <summary>

        /// 同步TCP服务器

        /// </summary>

        /// <param name="listenPort">监听的端口</param>

        public TCPServer(int listenPort)

            : this(IPAddress.Any, listenPort, 1024)

        {

        }

 

        /// <summary>

        /// 同步TCP服务器

        /// </summary>

        /// <param name="localEP">监听的终结点</param>

        public TCPServer(IPEndPoint localEP)

            : this(localEP.Address, localEP.Port, 1024)

        {

        }

 

        /// <summary>

        /// 同步TCP服务器

        /// </summary>

        /// <param name="localIPAddress">监听的IP地址</param>

        /// <param name="listenPort">监听的端口</param>

        /// <param name="maxClient">最大客户端数量</param>

        public TCPServer(IPAddress localIPAddress, int listenPort, int maxClient)

        {

            this.Address = localIPAddress;

            this.Port = listenPort;

            this.Encoding = Encoding.Default;

 

            _maxClient = maxClient;

            _clients = new List<TCPClientHandle>();

            _listener = new TcpListener(new IPEndPoint(this.Address, this.Port));

        }

 

        #endregion

 

        #region Method

        /// <summary>

        /// 启动服务器

        /// </summary>

        public void Start()

        {

            if (!IsRunning)

            {

                IsRunning = true;

                _listener.Start();

                Thread thread = new Thread(Accept);

                thread.Start();

            }

        }

        /// <summary>

        /// 开始进行监听

        /// </summary>

        private void Accept()

        {

            TCPClientHandle handle;

            while (IsRunning)

            {

                TcpClient client = _listener.AcceptTcpClient();

                if (_clientCount >= _maxClient)

                {

                    //TODO 触发事件

                }

                else

                {

                    handle = new TCPClientHandle(client);

                    _clientCount++;

                    _clients.Add(handle);

 

                    //TODO 创建一个处理客户端的线程并启动

                    //使用线程池来操作

                    new Thread(new ThreadStart(handle.RecevieData)).Start();

                }

            }

 

        }

        /// <summary>

        /// 停止服务器

        /// </summary>

        public void Stop()

        {

            if (IsRunning)

            {

                IsRunning = false;

                _listener.Stop();

                //TODO 关闭对所有客户端的连接

            }

        }

        /// <summary>

        /// 发送函数

        /// </summary>

        public void Send(string msg, TcpClient client)

        {

            //TODO

        }

 

        #endregion

 

        #region 事件

 

        /// <summary>

        /// 与客户端的连接已建立事件

        /// </summary>

        public event EventHandler<TCPEventArgs> ClientConnected;

        /// <summary>

        /// 与客户端的连接已断开事件

        /// </summary>

        public event EventHandler<TCPEventArgs> ClientDisconnected;

 

        /// <summary>

        /// 触发客户端连接事件

        /// </summary>

        /// <param name="state"></param>

        private void RaiseClientConnected(TCPClientHandle handle)

        {

            if (ClientConnected != null)

            {

                ClientConnected(this, new TCPEventArgs(handle));

            }

        }

        /// <summary>

        /// 触发客户端连接断开事件

        /// </summary>

        /// <param name="client"></param>

        private void RaiseClientDisconnected(Socket client)

        {

            if (ClientDisconnected != null)

            {

                ClientDisconnected(this, new TCPEventArgs("连接断开"));

            }

        }

 

        /// <summary>

        /// 接收到数据事件

        /// </summary>

        public event EventHandler<TCPEventArgs> DataReceived;

 

        private void RaiseDataReceived(TCPClientHandle handle)

        {

            if (DataReceived != null)

            {

                DataReceived(this, new TCPEventArgs(handle));

            }

        }

 

        /// <summary>

        /// 数据发送事件

        /// </summary>

        public event EventHandler<TCPEventArgs> CompletedSend;

 

        /// <summary>

        /// 触发数据发送事件

        /// </summary>

        /// <param name="state"></param>

        private void RaiseCompletedSend(TCPClientHandle handle)

        {

            if (CompletedSend != null)

            {

                CompletedSend(this, new TCPEventArgs(handle));

            }

        }

 

 

        /// <summary>

        /// 网络错误事件

        /// </summary>

        public event EventHandler<TCPEventArgs> NetError;

        /// <summary>

        /// 触发网络错误事件

        /// </summary>

        /// <param name="state"></param>

        private void RaiseNetError(TCPClientHandle handle)

        {

            if (NetError != null)

            {

                NetError(this, new TCPEventArgs(handle));

            }

        }

 

        /// <summary>

        /// 异常事件

        /// </summary>

        public event EventHandler<TCPEventArgs> OtherException;

        /// <summary>

        /// 触发异常事件

        /// </summary>

        /// <param name="state"></param>

        private void RaiseOtherException(TCPClientHandle handle, string descrip)

        {

            if (OtherException != null)

            {

                OtherException(this, new TCPEventArgs(descrip, handle));

            }

        }

        private void RaiseOtherException(TCPClientHandle handle)

        {

            RaiseOtherException(handle, "");

        }

 

        #endregion

 

        #region Close

 

        /// <summary>

        /// 关闭一个与客户端之间的会话

        /// </summary>

        /// <param name="handle">需要关闭的客户端会话对象</param>

        public void Close(TCPClientHandle handle)

        {

            if (handle != null)

            {

                _clients.Remove(handle);

                handle.Dispose();

                _clientCount--;

                //TODO 触发关闭事件

 

            }

        }

        /// <summary>

        /// 关闭所有的客户端会话,与所有的客户端连接会断开

        /// </summary>

        public void CloseAllClient()

        {

            foreach (TCPClientHandle handle in _clients)

            {

                Close(handle);

            }

            _clientCount = 0;

            _clients.Clear();

        }

        #endregion

 

        #region 释放

        /// <summary>

        /// Performs application-defined tasks associated with freeing,

        /// releasing, or resetting unmanaged resources.

        /// </summary>

        public void Dispose()

        {

            Dispose(true);

            GC.SuppressFinalize(this);

        }

 

        /// <summary>

        /// Releases unmanaged and - optionally - managed resources

        /// </summary>

        /// <param name="disposing"><c>true</c> to release

        /// both managed and unmanaged resources; <c>false</c>

        /// to release only unmanaged resources.</param>

        protected virtual void Dispose(bool disposing)

        {

            if (!this.disposed)

            {

                if (disposing)

                {

                    try

                    {

                        Stop();

                        if (_listener != null)

                        {

                            _listener = null;

                        }

                    }

                    catch (SocketException)

                    {

                        //TODO 异常

                    }

                }

                disposed = true;

            }

        }

        #endregion

    }

}

Copy after login

Client processing encapsulation class

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

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Net.Sockets;

using System.IO;

 

namespace NetFrame.Net.TCP.Listener.Synchronous

{

    /// <summary>

    /// TcpListener实现同步TCP服务器 的客户端连接处理类

    /// </summary>

    public class TCPClientHandle

    {

        private TcpClient _tcpclient;

 

        private BinaryReader rs;

 

        private BinaryWriter ws;

 

        /// <summary>

        /// 标识是否与客户端相连接

        /// </summary>

        private bool _is_connect;

        public bool IsConnect

        {

            get { return _is_connect; }

            set { _is_connect = value; }

        }

 

        /// <summary>

        /// 数据接受缓冲区

        /// </summary>

        private byte[] _recvBuffer;

 

        public TCPClientHandle(TcpClient client)

        {

            _tcpclient = client;

            rs = new BinaryReader(client.GetStream());

            ws = new BinaryWriter(client.GetStream());

            // NetworkStream ns = tmpTcpClient.GetStream();

            // if(ns.CanRead&&ns.CanWrite)

            _recvBuffer=new byte[client.ReceiveBufferSize];

        }

 

        /// <summary>

        /// 接受数据

        /// </summary>

        public void RecevieData()

        {

            int len = 0;

            while (_is_connect)

            {

                try

                {

                    len = rs.Read(_recvBuffer, 0, _recvBuffer.Length);

                }

                catch (Exception)

                {

                    break;

                }

                if (len == 0)

                {

                    //the client has disconnected from server

                    break;

                }

                //TODO 处理收到的数据

                 

            }

        }

        /// <summary>

        /// 向客户端发送数据

        /// </summary>

        /// <param name="msg"></param>

        public void SendData(string msg)

        {

            byte[] data = Encoding.Default.GetBytes(msg);

            try

            {

                ws.Write(data, 0, data.Length);

                ws.Flush();

            }

            catch (Exception)

            {

                //TODO 处理异常

            }

        }

 

        #region 事件

 

 

        //TODO 消息发送事件

        //TODO 数据收到事件

        //TODO 异常处理事件

 

        #endregion

 

        #region 释放

        /// <summary>

        /// Performs application-defined tasks associated with freeing,

        /// releasing, or resetting unmanaged resources.

        /// </summary>

        public void Dispose()

        {

            _is_connect = false;

            if (_tcpclient != null)

            {

                _tcpclient.Close();

                _tcpclient = null;

            }

            GC.SuppressFinalize(this);

        }

 

        #endregion

    }

}

Copy after login


Tcp server event parameter class

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

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace NetFrame.Net.TCP.Listener.Synchronous

{

    /// <summary>

    /// 同步TcpListener TCP服务器事件类

    /// </summary>

    public class TCPEventArgs : EventArgs

    {

        /// <summary>

        /// 提示信息

        /// </summary>

        public string _msg;

 

        /// <summary>

        /// 客户端状态封装类

        /// </summary>

        public TCPClientHandle _handle;

 

        /// <summary>

        /// 是否已经处理过了

        /// </summary>

        public bool IsHandled { get; set; }

 

        public TCPEventArgs(string msg)

        {

            this._msg = msg;

            IsHandled = false;

        }

        public TCPEventArgs(TCPClientHandle handle)

        {

            this._handle = handle;

            IsHandled = false;

        }

        public TCPEventArgs(string msg, TCPClientHandle handle)

        {

            this._msg = msg;

            this._handle = handle;

            IsHandled = false;

        }

    }

}

Copy after login

The above is the C# network programming series Article (4) TcpListener implements synchronization of the content of the TCP server. For more related content, please pay attention to the PHP Chinese website (www.php.cn)!


Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot Article Tags

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Active Directory with C# Active Directory with C# Sep 03, 2024 pm 03:33 PM

Active Directory with C#

Access Modifiers in C# Access Modifiers in C# Sep 03, 2024 pm 03:24 PM

Access Modifiers in C#

Random Number Generator in C# Random Number Generator in C# Sep 03, 2024 pm 03:34 PM

Random Number Generator in C#

C# Data Grid View C# Data Grid View Sep 03, 2024 pm 03:32 PM

C# Data Grid View

Patterns in C# Patterns in C# Sep 03, 2024 pm 03:33 PM

Patterns in C#

C# StringReader C# StringReader Sep 03, 2024 pm 03:23 PM

C# StringReader

BinaryWriter in C# BinaryWriter in C# Sep 03, 2024 pm 03:22 PM

BinaryWriter in C#

C# StringWriter C# StringWriter Sep 03, 2024 pm 03:23 PM

C# StringWriter

See all articles