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 }