直接用Socket TCP开发网络游戏(一)

本教程学习自Siki学院

1,控制台应用程序 ,创建服务器端  代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
namespace TCP服务端
{
    class Program
    {
        static void Main(string[] args)
        {
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            ///申请id    127.0.0.1  本机
            //IPAddress ip = new IPAddress(new byte[] { 192, 168, 1, 7 });
            IPAddress ipAddress = IPAddress.Parse("192.168.1.7");
            //申请端口号
            IPEndPoint endPoint = new IPEndPoint(ipAddress, 88);
            //绑定ip和端口号
            serverSocket.Bind(endPoint);
            serverSocket.Listen(0);//开始监听端口号(0 没有数量限制)
           Socket clientSocket= serverSocket.Accept();//接收一个客户端的连接
           ///向客户端发送消息
            string msg = "Hello client !你好。。";
           byte[] data= System.Text.Encoding.UTF8.GetBytes(msg); //转成字符串数组进行传递
            clientSocket.Send(data);


            /// 接收一条消息
            /// 
            byte[] dataBuffer = new byte[1024];


            ///数据没有填充满,前多少个有数据 ,count 指接收到了多少数据
            ///
            int count =    clientSocket.Receive(dataBuffer);


            string msgReceive = System.Text.Encoding.UTF8.GetString(dataBuffer,0, count);


            Console.WriteLine(msgReceive);


            Console.ReadKey();
            clientSocket.Close();//关闭客户端的连接
            serverSocket.Close();//关闭自身的连接
        }
    }
}


2,创建客户端代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
namespace TCP客户端
{
    class Program
    {
        static void Main(string[] args)
        {
            //创建客户端
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //与服务器建立连接0
            clientSocket.Connect(new IPEndPoint(IPAddress.Parse("192.168.1.7"), 88));

            byte[] data = new byte[1024]; //建立

            int count = clientSocket.Receive(data); //接受count个字节

            string msg = System.Text.Encoding.UTF8.GetString(data, 0, count); //接收到的信息
            Console.WriteLine(msg);
            string s = Console.ReadLine();
            
            byte[] buf= Encoding.UTF8.GetBytes(s);

            clientSocket.Send(buf);

            Console.ReadKey();
            clientSocket.Close();

        }
    }
}


目前的功能:


先启动服务器,服务器会像客户端发送一条消息,然后客户端再像服务器发送一条输入的消息,


3,现在改进后 变成异步加载 

服务器端和客户端  先启动服务器端,再启动客户端  ,

服务器端代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
namespace TCP服务端
{
    class Program
    {
        static void Main(string[] args)
        {
            StartServerAsync();
            Console.ReadKey();
        }
        /// 
        /// 直接加载
        /// 
        void StartServerSvnc()
        {
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            ///申请id    127.0.0.1  本机
            //IPAddress ip = new IPAddress(new byte[] { 192, 168, 1, 7 });
            IPAddress ipAddress = IPAddress.Parse("192.168.1.7");
            //申请端口号
            IPEndPoint endPoint = new IPEndPoint(ipAddress, 88);
            //绑定ip和端口号
            serverSocket.Bind(endPoint);
            serverSocket.Listen(0);//开始监听端口号(0 没有数量限制)
            Socket clientSocket = serverSocket.Accept();//接收一个客户端的连接
                                                        ///向客户端发送消息
            string msg = "Hello client !你好。。";
            byte[] data = System.Text.Encoding.UTF8.GetBytes(msg); //转成字符串数组进行传递
            clientSocket.Send(data);

            /// 接收一条消息
            /// 
            byte[] dataBuffer = new byte[1024];

            ///数据没有填充满,前多少个有数据 ,count 指接收到了多少数据
            ///
            int count = clientSocket.Receive(dataBuffer);

            string msgReceive = System.Text.Encoding.UTF8.GetString(dataBuffer, 0, count);

            Console.WriteLine(msgReceive);


            Console.ReadKey();

            clientSocket.Close();//关闭客户端的连接

            serverSocket.Close();//关闭自身的连接

        }
        /// 
        /// 异步加载
        /// 
        static    void StartServerAsync()
        {
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            ///申请id    127.0.0.1  本机
            //IPAddress ip = new IPAddress(new byte[] { 192, 168, 1, 7 });
            IPAddress ipAddress = IPAddress.Parse("192.168.1.7");
            //申请端口号
            IPEndPoint endPoint = new IPEndPoint(ipAddress, 88);
            //绑定ip和端口号
            serverSocket.Bind(endPoint);
            serverSocket.Listen(0);//开始监听端口号(0 没有数量限制)
            Socket clientSocket = serverSocket.Accept();//接收一个客户端的连接
                                                        ///向客户端发送消息
            string msg = "Hello client !你好。。";
            byte[] data = System.Text.Encoding.UTF8.GetBytes(msg); //转成字符串数组进行传递
            clientSocket.Send(data);


            ////异步加载

           
      
            clientSocket.BeginReceive(dataBuffor, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);

         
        }

       static byte[] dataBuffor = new byte[1024];


       static   void ReceiveCallBack(IAsyncResult ar)
        {
            Socket clientSocket = ar.AsyncState as Socket;
           int count=    clientSocket.EndReceive(ar); //v结束挂起的异步读取。接收到的字节数。

           string msg= Encoding.UTF8.GetString(dataBuffor, 0, count);
            Console.WriteLine("客户端接受到的数据为: "+ msg);
            clientSocket.BeginReceive(dataBuffor, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);

        
        }


        }
}

客户端代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
namespace TCP客户端
{
    class Program
    {
        static void Main(string[] args)
        {
            //创建客户端
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //与服务器建立连接0
            clientSocket.Connect(new IPEndPoint(IPAddress.Parse("192.168.1.7"), 88));

            byte[] data = new byte[1024]; //建立

            int count = clientSocket.Receive(data); //接受count个字节

            string msg = System.Text.Encoding.UTF8.GetString(data, 0, count); //接收到的信息

            Console.WriteLine(msg);

            while (true)
            {
                string s = Console.ReadLine();
                

                byte[] buf = Encoding.UTF8.GetBytes(s);

                clientSocket.Send(buf);

            }
            Console.ReadKey();

            clientSocket.Close();

        }
    }
}

4 现在要实现 多个客户端的连接

所以在客户端的连接也用到异步的方式,连接一个客户端就进行一次异步。现在客户端代码不要动,服务器端代码实现如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
namespace TCP服务端
{
    class Program
    {
        static void Main(string[] args)
        {
            StartServerAsync();
            Console.ReadKey();
        }
        /// 
        /// 直接加载
        /// 
        void StartServerSvnc()
        {
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            ///申请id    127.0.0.1  本机
            //IPAddress ip = new IPAddress(new byte[] { 192, 168, 1, 7 });
            IPAddress ipAddress = IPAddress.Parse("192.168.1.7");
            //申请端口号
            IPEndPoint endPoint = new IPEndPoint(ipAddress, 88);
            //绑定ip和端口号
            serverSocket.Bind(endPoint);
            serverSocket.Listen(0);//开始监听端口号(0 没有数量限制)
            Socket clientSocket = serverSocket.Accept();//接收一个客户端的连接
                                                        ///向客户端发送消息
            string msg = "Hello client !你好。。";
            byte[] data = System.Text.Encoding.UTF8.GetBytes(msg); //转成字符串数组进行传递
            clientSocket.Send(data);

            /// 接收一条消息
            /// 
            byte[] dataBuffer = new byte[1024];

            ///数据没有填充满,前多少个有数据 ,count 指接收到了多少数据
            ///
            int count = clientSocket.Receive(dataBuffer);

            string msgReceive = System.Text.Encoding.UTF8.GetString(dataBuffer, 0, count);

            Console.WriteLine(msgReceive);


            Console.ReadKey();

            clientSocket.Close();//关闭客户端的连接

            serverSocket.Close();//关闭自身的连接

        }
        /// 
        /// 异步加载
        /// 
        static    void StartServerAsync()
        {
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            ///申请id    127.0.0.1  本机
            //IPAddress ip = new IPAddress(new byte[] { 192, 168, 1, 7 });
            IPAddress ipAddress = IPAddress.Parse("192.168.1.7");
            //申请端口号
            IPEndPoint endPoint = new IPEndPoint(ipAddress, 88);
            //绑定ip和端口号
            serverSocket.Bind(endPoint);
            serverSocket.Listen(0);//开始监听端口号(0 没有数量限制)



            //Socket clientSocket = serverSocket.Accept();//接收一个客户端的连接
            //                                            ///向客户端发送消息

            //要想多个客户端连接就要把 客户端的连接的接收也做成异步的

            /* Socket clientSocket = */

            serverSocket.BeginAccept(AsyncCallback, serverSocket);
            
            } 

            ////异步加载
        static void AsyncCallback(IAsyncResult ar)
        {
            Socket serverSocket = ar.AsyncState as Socket; //把传进来的server进行转型, 

            Socket clientSocket =  serverSocket.EndAccept(ar);  //完成接收

            string msg = "Hello client !你好。。";

            byte[] data = System.Text.Encoding.UTF8.GetBytes(msg); //转成字符串数组进行传递

            clientSocket.Send(data);

            clientSocket.BeginReceive(dataBuffor, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);
            
            serverSocket.BeginAccept(AsyncCallback, serverSocket); //再次调用 处理下一个客户端的连接


        }



        static byte[] dataBuffor = new byte[1024];


       static   void ReceiveCallBack(IAsyncResult ar)
        {
            Socket clientSocket = ar.AsyncState as Socket;
           int count=    clientSocket.EndReceive(ar); //v结束挂起的异步读取。接收到的字节数。

           string msg= Encoding.UTF8.GetString(dataBuffor, 0, count);
            Console.WriteLine("客户端接受到的数据为: "+ msg);
            clientSocket.BeginReceive(dataBuffor, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);

        
        }


        }
}

5,在服务器处理客户端的连接正常关闭和非正常关闭,

现在所处的问题就是 如果多开启几个客户端 ,关闭客户端窗口后就会结束程序,出现异常 异常为非法关闭客户端 所以需要try cath捕获异常

 出现异常后关闭改客户端。再 然后 在客户端输出‘c’ 为关闭客户端,这时候依然会出现问题 服务器端依然会接收到长度为0的字符串一直输出,这时候需要判断正常关闭客户端的操作 通过发送为0长度的字符串来判断。 服务器客户端的代码实现如下。

服务器:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
namespace TCP服务端
{
    class Program
    {
        static void Main(string[] args)
        {
            StartServerAsync();
            Console.ReadKey();
        }
        /// 
        /// 直接加载
        /// 
        void StartServerSvnc()
        {
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            ///申请id    127.0.0.1  本机
            //IPAddress ip = new IPAddress(new byte[] { 192, 168, 1, 7 });
            IPAddress ipAddress = IPAddress.Parse("192.168.1.7");
            //申请端口号
            IPEndPoint endPoint = new IPEndPoint(ipAddress, 88);
            //绑定ip和端口号
            serverSocket.Bind(endPoint);
            serverSocket.Listen(0);//开始监听端口号(0 没有数量限制)
            Socket clientSocket = serverSocket.Accept();//接收一个客户端的连接
                                                        ///向客户端发送消息
            string msg = "Hello client !你好。。";
            byte[] data = System.Text.Encoding.UTF8.GetBytes(msg); //转成字符串数组进行传递
            clientSocket.Send(data);

            /// 接收一条消息
            /// 
            byte[] dataBuffer = new byte[1024];

            ///数据没有填充满,前多少个有数据 ,count 指接收到了多少数据
            ///
            int count = clientSocket.Receive(dataBuffer);

            string msgReceive = System.Text.Encoding.UTF8.GetString(dataBuffer, 0, count);

            Console.WriteLine(msgReceive);


            Console.ReadKey();

            clientSocket.Close();//关闭客户端的连接

            serverSocket.Close();//关闭自身的连接

        }
        /// 
        /// 异步加载
        /// 
        static void StartServerAsync()
        {
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            ///申请id    127.0.0.1  本机
            //IPAddress ip = new IPAddress(new byte[] { 192, 168, 1, 7 });
            IPAddress ipAddress = IPAddress.Parse("192.168.1.7");
            //申请端口号
            IPEndPoint endPoint = new IPEndPoint(ipAddress, 88);
            //绑定ip和端口号
            serverSocket.Bind(endPoint);
            serverSocket.Listen(0);//开始监听端口号(0 没有数量限制)



            //Socket clientSocket = serverSocket.Accept();//接收一个客户端的连接
            //                                            ///向客户端发送消息

            //要想多个客户端连接就要把 客户端的连接的接收也做成异步的

            /* Socket clientSocket = */

            serverSocket.BeginAccept(AsyncCallback, serverSocket);

        }

        ////异步加载
        static void AsyncCallback(IAsyncResult ar)
        {

            //把传进来的server进行转型, 

            ////如果不添加try catch 异常捕捉的话 如果强制关闭一个客户端的话,服务器程序就会终止

            Socket serverSocket = ar.AsyncState as Socket;

            Socket clientSocket = serverSocket.EndAccept(ar);  //完成接收

            string msg = "Hello client !你好。。";

            byte[] data = System.Text.Encoding.UTF8.GetBytes(msg); //转成字符串数组进行传递

            clientSocket.Send(data);

            clientSocket.BeginReceive(dataBuffor, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);

            serverSocket.BeginAccept(AsyncCallback, serverSocket); //再次调用 处理下一个客户端的连接
            
        }

        static byte[] dataBuffor = new byte[1024];

        static void ReceiveCallBack(IAsyncResult ar)
        {
            Socket clientSocket = null;

            try
            {
                clientSocket = ar.AsyncState as Socket;

                int count = clientSocket.EndReceive(ar); //v结束挂起的异步读取。接收到的字节数。
                if (count==0) //如果输入‘c’ 客户端正常关闭  服务器会一直接收到空数据, 通过判断接受到的长度 如果为0 是正常关闭 关闭客户端 return就好了
                {
                    clientSocket.Close();return;
                }
                string msg = Encoding.UTF8.GetString(dataBuffor, 0, count);

                Console.WriteLine("客户端接受到的数据为: " + msg);

                clientSocket.BeginReceive(dataBuffor, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);

        }

            catch (Exception e)
            {
                Console.WriteLine(e);

                if (clientSocket != null)
                {
                    clientSocket.Close();
                }
           }
        }
    }
}

客户端:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
namespace TCP客户端
{
    class Program
    {
        static void Main(string[] args)
        {
            //创建客户端
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //与服务器建立连接0
            clientSocket.Connect(new IPEndPoint(IPAddress.Parse("192.168.1.7"), 88));

            byte[] data = new byte[1024]; //建立

            int count = clientSocket.Receive(data); //接受count个字节

            string msg = System.Text.Encoding.UTF8.GetString(data, 0, count); //接收到的信息

            Console.WriteLine(msg);

            while (true)
            {
                string s = Console.ReadLine();

                if (s=="c")
                {
                    clientSocket.Close(); return;
                }


                byte[] buf = Encoding.UTF8.GetBytes(s);

                clientSocket.Send(buf);

            }
            Console.ReadKey();

            clientSocket.Close();

        }
    }
}

6,粘包和分包

粘包 如图所示 直接用Socket TCP开发网络游戏(一)_第1张图片

分包问题, 把一个特别长的字符串分割成多条信息发送

直接用Socket TCP开发网络游戏(一)_第2张图片


7,粘包和分包的解决方案

直接用Socket TCP开发网络游戏(一)_第3张图片


直接用Socket TCP开发网络游戏(一)_第4张图片直接用Socket TCP开发网络游戏(一)_第5张图片


8,在客户端发送数据时加上数据的长度,

现在我们要在客户端中做出一个类 ,这个类专门用来结合前面的个数和后面的内容,

代码实现如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TCP客户端
{
    class Message
    {

        public static byte[] GetBytes(string data)
        {
            byte[] dataBytes = Encoding.UTF8.GetBytes(data); //这个是要传递的数据的内容

            int dataLength = dataBytes.Length;//这个是发送数据的长度

            byte[] lengthBytes = BitConverter.GetBytes(dataLength); //前面的数据长度 的数组


            byte[] newBytes = lengthBytes.Concat(dataBytes).ToArray(); //组成一个新的字节

            return newBytes;

        }

    }
}

然后修改客户端的发送消息的情况;

代码实现如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
namespace TCP客户端
{
    class Program
    {
        static void Main(string[] args)
        {
            //创建客户端
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //与服务器建立连接0
            clientSocket.Connect(new IPEndPoint(IPAddress.Parse("192.168.1.7"), 88));

            byte[] data = new byte[1024]; //建立

            int count = clientSocket.Receive(data); //接受count个字节

            string msg = System.Text.Encoding.UTF8.GetString(data, 0, count); //接收到的信息

            Console.WriteLine(msg);

            //while (true)
            //{
            //    string s = Console.ReadLine();

            //    if (s=="c")
            //    {
            //        clientSocket.Close(); return;
            //    }


            //    byte[] buf = Encoding.UTF8.GetBytes(s);

            //    clientSocket.Send(buf);

            //}
            for (int i = 0; i < 100; i++)
            {
                clientSocket.Send(Message.GetBytes(i.ToString()));
            }
            Console.ReadKey();

            clientSocket.Close();

        }
    }
}


然后现在发送的消息 在服务器没解析 出现的情况如图,现在我们需要解析:

直接用Socket TCP开发网络游戏(一)_第6张图片

9,服务器端的接收和解析数据 

修改服务器端代码 然后新建一个Message类进行解析数据

代码实现如下;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
namespace TCP服务端
{
    class Program
    {
        static void Main(string[] args)
        {
            StartServerAsync();
            Console.ReadKey();
        }

        static  Message msg = new Message();
        /// 
        /// 直接加载
        /// 
        void StartServerSvnc()
        {
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            ///申请id    127.0.0.1  本机
            //IPAddress ip = new IPAddress(new byte[] { 192, 168, 1, 7 });
            IPAddress ipAddress = IPAddress.Parse("192.168.1.7");
            //申请端口号
            IPEndPoint endPoint = new IPEndPoint(ipAddress, 88);
            //绑定ip和端口号
            serverSocket.Bind(endPoint);
            serverSocket.Listen(0);//开始监听端口号(0 没有数量限制)
            Socket clientSocket = serverSocket.Accept();//接收一个客户端的连接
                                                        ///向客户端发送消息
            string msg = "Hello client !你好。。";
            byte[] data = System.Text.Encoding.UTF8.GetBytes(msg); //转成字符串数组进行传递
            clientSocket.Send(data);

            /// 接收一条消息
            /// 
            byte[] dataBuffer = new byte[1024];

            ///数据没有填充满,前多少个有数据 ,count 指接收到了多少数据
            ///
            int count = clientSocket.Receive(dataBuffer);

            string msgReceive = System.Text.Encoding.UTF8.GetString(dataBuffer, 0, count);

            Console.WriteLine(msgReceive);


            Console.ReadKey();

            clientSocket.Close();//关闭客户端的连接

            serverSocket.Close();//关闭自身的连接

        }
        /// 
        /// 异步加载
        /// 
        static void StartServerAsync()
        {
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            ///申请id    127.0.0.1  本机
            //IPAddress ip = new IPAddress(new byte[] { 192, 168, 1, 7 });
            IPAddress ipAddress = IPAddress.Parse("192.168.1.7");
            //申请端口号
            IPEndPoint endPoint = new IPEndPoint(ipAddress, 88);
            //绑定ip和端口号
            serverSocket.Bind(endPoint);
            serverSocket.Listen(0);//开始监听端口号(0 没有数量限制)
            
            //Socket clientSocket = serverSocket.Accept();//接收一个客户端的连接
            //                                            ///向客户端发送消息

            //要想多个客户端连接就要把 客户端的连接的接收也做成异步的

            /* Socket clientSocket = */

            serverSocket.BeginAccept(AsyncCallback, serverSocket);

        }

        ////异步加载
        static void AsyncCallback(IAsyncResult ar)
        {

            //把传进来的server进行转型, 

            ////如果不添加try catch 异常捕捉的话 如果强制关闭一个客户端的话,服务器程序就会终止

            Socket serverSocket = ar.AsyncState as Socket;

            Socket clientSocket = serverSocket.EndAccept(ar);  //完成接收

            string msgStr = "Hello client !你好。。";

            byte[] data = System.Text.Encoding.UTF8.GetBytes(msgStr); //转成字符串数组进行传递

            clientSocket.Send(data);



            clientSocket.BeginReceive(msg.Data, msg.StartIndex, msg.RemaniSize , SocketFlags.None, ReceiveCallBack, clientSocket);

            serverSocket.BeginAccept(AsyncCallback, serverSocket); //再次调用 处理下一个客户端的连接
            
        }

        static byte[] dataBuffor = new byte[1024];

        static void ReceiveCallBack(IAsyncResult ar)
        {
            Socket clientSocket = null;

            try
            {
                clientSocket = ar.AsyncState as Socket;

                int count = clientSocket.EndReceive(ar); //v结束挂起的异步读取。接收到的字节数。
                ///count是读取到的数据, 也就是StartIndex

                if (count==0) //如果输入‘c’ 客户端正常关闭  服务器会一直接收到空数据, 通过判断接受到的长度 如果为0 是正常关闭 关闭客户端 return就好了
                {
                    clientSocket.Close();return;
                }

                msg.AddCount(count);//更新了message的count


                ///在message那边解析接收到的数据;

                msg.ReadMessage();


                clientSocket.BeginReceive(msg.Data, msg.StartIndex, msg.RemaniSize, SocketFlags.None, ReceiveCallBack, clientSocket); //等待客户端的再次发送

                ///这种读取的方式不对, 我们就不用这种了!
                //string msgs= Encoding.UTF8.GetString(dataBuffor, 0, count);
                //Console.WriteLine("客户端接受到的数据为: " + msgs);
                // clientSocket.BeginReceive(dataBuffor, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);

              
            }

            catch (Exception e)
            {
                Console.WriteLine(e);

                if (clientSocket != null)
                {
                    clientSocket.Close();
                }
           }
        }
    }
}

Message类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TCP服务端
{
    class Message
    {
        private byte[] data = new byte[1024]; //这个数组用来存取我们读取到的数据,让消息的长度最少能存的下1024 ,如果说最大的消息数组存不下的话 就没办法完整的读取这条消息了
        //如果消息不完整 我们不处理。我们会读取下一条
        private int startIndex = 0;//标识位,表示现在数据存储在什么位置了 ,如果没数据 sartIndex从0开始,如果存了10个之后 这个startIndex就等于10;
                                   //再来数据的话就从10开始存,同时也代表了存了多少个字节的数据。

        /// 
        /// 这个数组用来存取我们读取到的数据
        /// 
        public byte[] Data
        {
            get { return data; }
        }
        /// 
        /// 代表存储了多少个字节的数据
        /// 
        public int StartIndex
        {
            get { return startIndex; }
        }
        /// 
        /// 剩余的空间
        /// 
        public int RemaniSize
        {
            get { return data.Length - startIndex; }
        }
        /// 
        /// 更新了多少数据
        /// 
        /// 
        public void AddCount(int count)
        {
            startIndex += count;
        }
        /// 
        /// 解析数据或者叫做读取数据
        /// 
        public void ReadMessage()
        {
            while (true)
            {
                if (startIndex <= 4) return;
                int count = BitConverter.ToInt32(data, 0);//这个只占前四个字节  ,变成int 就是数据长度
                if ((startIndex - 4) >= count) //(startIndex-4)是剩余数据的长度 ,大于count 就说明数据是完整的
                {
                    string s = Encoding.UTF8.GetString(data, 4, count);
                    Console.WriteLine("解析出来一条数据 :" + s);
                    Array.Copy(data, count + 4, data, 0, startIndex - 4 - count);

                    startIndex -= (count + 4); //移动完了之后更新startIndex
                }
                else
                {
                    break;
                }
            }

          
        }

      
    }
}


切记修改完成后要从新生成一下!!


10,C#连接mysql数据库 前面的博客中也有些到。

 可以参考http://blog.csdn.net/qq_36848370/article/details/76558718

先引入 C盘下的  Program Files(86) 下的 MySQL下的 Connector.net 6.9 下的Assemblies 下的 v4.5 下的 MySql.Data.dll

代码实现如下 :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MySql.Data.MySqlClient;
namespace MySql数据库操作
{
    class Program
    {
        static void Main(string[] args)
        {
            string connStr = "Database=test007;Data Source=127.0.0.1;port=3306;User Id=root;Password=root";

            MySqlConnection conn = new MySqlConnection(connStr);

            conn.Open();
            #region 查询

            #region 读取多条
            //MySqlCommand cmd = new MySqlCommand("select * from user ", conn);

            #endregion
            #region 读取一条
            //  MySqlCommand cmd = new MySqlCommand("select * from user where id = 1", conn);

            #endregion

            //MySqlDataReader reader = cmd.ExecuteReader();

            #region 读取一条
            // if (reader.HasRows) //得到一个值指示是否MySqlDataReader包含一个或多个行。
            // {
            //reader.Read(); //表示读取一条消息,多次读取多次调用
            //string username = reader.GetString("username");
            //string passwore = reader.GetString("password");
            //Console.WriteLine(username + " " + passwore);

            //  }
            #endregion
            #region 读取多条
            //while (reader.Read())
            //{
            //    string username = reader.GetString("username");
            //    string passwore = reader.GetString("password");
            //    Console.WriteLine(username + " " + passwore);
            //}

            #endregion


            //reader.Close();

            #endregion
            #region 插入
            string username = "zain"; string password = "zain";  ///用户组拼 有bug 用户可以恶意输入sql语句 下节课再解决
            MySqlCommand cmd = new MySqlCommand("insert into user set username='" + username + "'" + ", password='" + password + "'", conn);

            cmd.ExecuteNonQuery();//执行插入  并返回插入的行数
            Console.WriteLine(cmd.ExecuteNonQuery()); 
            #endregion
            conn.Close();
            Console.ReadKey();
        }
    }
}


请看(二)。



你可能感兴趣的:(Unity,3D,C#)