1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Net.Sockets;
 5 using System.Net;
 6 using System.Text;
 7 using System.Threading.Tasks;
 8 
 9 namespace GameServer.Server
10 {
11      class Server
12     {
13         //定义一些变量存储一些东西
14         private IPEndPoint _ipEndPoint;
15         private Socket serverSocket;
16         private List<Client> clientList;//把所有的客户端都管理起来,创建一个list集合
17                                         //给他提供一个空的构造方法,后期进行一个设置
18         public Server()
19         {
20 
21         }
22         //给他提供一个带参数的构造方法,我们开启服务端的时候需要ip和端口号。
23         public Server(string ipStr, int port)
24         {
25             SetIpAndPort(ipStr, port);
26         }
27         //set方法设置IP和端口号
28         public void SetIpAndPort(string ipStr, int port)
29         {
30             _ipEndPoint = new IPEndPoint(IPAddress.Parse(ipStr), port);
31         }
32         //进行启动server端,启动监听
33         public void Start()
34         {
35             serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
36             serverSocket.Bind(_ipEndPoint);
37             serverSocket.Listen(0);
38             serverSocket.BeginAccept(AcceptCallBack, null);
39         }
40         //使用异步的方式调用多个客户端的连接
41         private void AcceptCallBack(IAsyncResult ar)
42         {
43             Socket clientSocket = serverSocket.EndAccept(ar);//得到跟客户端的连接,接收到客户端的连接
44             Client client = new Client(clientSocket, this);
45             client.Start();
46             clientList.Add(client);
47 
48         }
49         public void RemoveClient(Client client)
50         {
51             //多个客户端可能都要去访问clientList去进行移除,把他锁定了之后再进行移除,防止多线程同时访问共享的clientList矛盾异常
52             lock (clientList)
53             {
54                 clientList.Remove(client);
55 
56             }
57 
58         }
59     }
60 }
 
 1 using Microsoft.VisualBasic;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Net.Sockets;
 6 using System.Text;
 7 using System.Threading.Tasks;
 8 
 9 namespace GameServer.Server
10 {
11    
12         //专门用来处理与客户端的通信问题
13         class Client
14         {
15             private Socket clientSocket;
16             private Server server;//这边可能会与server交互,也需要持有一下
17             private Message msg=new Message();
18 
19             //给他提供一个空的构造方法,后期进行一个设置
20             public Client() { }
21             public Client(Socket clientSocket, Server server)
22             {
23                 this.clientSocket = clientSocket;
24                 this.server = server;
25             }
26             //表示开启监听
27             public void Start()
28             {
29                 clientSocket.BeginReceive(msg.Data, msg.StartIndex, msg.RemainSize, SocketFlags.None, ReceiveCallBack, null);//读取的时候要送到msg里面
30             }
31             private void ReceiveCallBack(IAsyncResult ar)
32             {
33                 try
34                 {
35                     int count = clientSocket.EndReceive(ar);//首先要接收数据的长度
36                     if (count == 0)
37                     {
38                         Close();
39                     }
40                 //todo  处理接收到的数据
41                 msg.ReadMessage(count);//进行消息的读取,读到消息之后转给controller去处理,然后由controller来决定需要做什么事情。
42                 Start();
43                 }
44                 catch (Exception e)
45                 {
46                     Console.WriteLine(e);
47                     Close();
48                 }
49             }
50             //专门断开连接的方法
51             private void Close()
52             {
53                 if (clientSocket != null)
54                     clientSocket.Close();
55                 server.RemoveClient(this);
56             }
57         }
58 }
 
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace GameServer.Server
 8 {
 9     class Message
10     {
11         private byte[] data = new byte[1024];
12         private int startIndex = 0;//我们存取了多少个字节的数据在数组里面
13 
14         //public void AddCount(int count)
15         //{
16         //    startIndex += count;
17         //}
18         public byte[] Data
19         {
20             get { return data; }
21         }
22         public int StartIndex
23         {
24             get { return startIndex; }
25         }
26         public int RemainSize
27         {
28             get { return data.Length - startIndex; }
29         }
30         /// <summary>
31         /// 解析数据或者叫做读取数据
32         /// </summary>
33         public void ReadMessage(int newDataAmount)
34         {
35             startIndex += newDataAmount;
36             while (true)
37             {
38                 if (startIndex <= 4) return;
39                 int count = BitConverter.ToInt32(data, 0);
40                 if ((startIndex - 4) >= count)
41                 {
42                     Console.WriteLine(startIndex);
43                     Console.WriteLine(count);
44                     string s = Encoding.UTF8.GetString(data, 4, count);
45                     Console.WriteLine("解析出来一条数据:" + s);
46                     Array.Copy(data, count + 4, data, 0, startIndex - 4 - count);
47                     startIndex -= (count + 4);
48                 }
49                 else
50                 {
51                     break;
52                 }
53             }
54         }
55     }
56 
57 }