前言

虽然最爱单机游戏,但是和朋友一起玩联网游戏可以获得双倍快乐!所以开始学习网络游戏相关的知识啦

1.1藏在幕后的服务端

客户端和客户端之间通过服务端的消息转发进行通信。
为了支撑很多玩家,游戏服务端通常采取分布式架构,也就是分区服务端,每个服务端负责不同区的玩家。
服务端和服务端之间通常使用TCP通信。

1.2网络连接的端点:Socket

网络上的两个程序通过一个双向的通信连接实现数据交换,这个连接的一端称为一个Socked。
每个Socket包含五种必备信息:

  • 连接使用的协议:TCP
  • 本地IP:192.168.200.11
  • 本地端口:1000
  • 远程IP:192.168.200.20
  • 远程端口:800
    两个不同主机的引用程序相互通信,就是先通过IP地址获取对方的计算机,再通过每个端口号获取这台计算机上的应用程序进行通信。(每个Socket连接都是从一台计算机的一个端口连接到另外一台计算的某个端口)

1.2.4Socket通信的流程

  1. 创建Socket对象,绑定本地端口(Bind),对于客户端而言,连接时(Connect)会由系统分配端口,可以省略绑定
  2. 服务端开启监听,等待客户端接入
  3. 客户端连接服务器
  4. 服务器接受连接
  5. 客户端和服务端通过Send和Receive手法数据,操作系统下自动完成数据确认、重传等
  6. 某一方Close连接,自动四次挥手

1.3开始网络编程:Echo

笔记均在代码注释中

1.3.1客户端代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net.Sockets;
using UnityEngine.UI;

public class Echo : MonoBehaviour
{
    //定义套接字
    Socket socket;
    //UGUI
    public InputField InputField;
    public Text text;

    //点击连接按钮
    public void Connection()
    {
        //新建sockect
        //地址族IPV4,套接字类型stream,协议类型
        socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        //connect
        //远程IP地址,远程端口,阻塞方法,卡住直到服务端回应、
        //自己建立服务器的话,ip地址和端口号就是这两个
        socket.Connect("127.0.0.1", 8888);
    }

    //点击发送按钮
    public void Send()
    {
        //send
        //string sendStr = InputField.text;
        string sendStr = System.DateTime.Now.ToString();
        //将str转化为字节流
        byte[] sendBytes = System.Text.Encoding.Default.GetBytes(sendStr);
        socket.Send(sendBytes);
        //Recv
        byte[] readBuff = new byte[1024];
        //接收数据的长度
        int count = socket.Receive(readBuff);
        string recvStr = System.Text.Encoding.Default.GetString(readBuff, 0, count);
        text.text = recvStr;
        //Close
        socket.Close();
    }
}

1.3.2服务端代码

using System;
using System.Net;
using System.Net.Sockets;

namespace ConsoleApp1
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello");
            //Socket
            Socket listenfd = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //Bind
            IPAddress ipAdr = IPAddress.Parse("127.0.0.1");//IP地址
            IPEndPoint ipEp = new IPEndPoint(ipAdr, 8888);//IP和端口
            //给listenfd套接字绑定IP和端口,"127.0.0.1"地址和8888号端口
            listenfd.Bind(ipEp);
            //Listen,等待客户端连接
            //0表示容纳等待接收的客户端连接数不受限制,1代表最多可容纳等待接受的连接数为1
            listenfd.Listen(0);
            Console.WriteLine("[服务器]启动成功");
            while (true)
            {
                //Accept
                //接收客户端连接,均为阻塞方法,如果没有客户端连接就不会向下执行
                //返回一个新客户端的socket对象,对于服务器来说
                //它有一个监听 Socket(listenfd)用来监听和应答客户端的连接,对每个客户端还有专门一个socket(connfd)用于处理客户端的数据
                Socket connfd = listenfd.Accept();
                Console.WriteLine("[服务器]Accetp");
                //Receive
                byte[] readBuff = new byte[1024];
                int count = connfd.Receive(readBuff);
                string readStr = System.Text.Encoding.Default.GetString(readBuff, 0, count);
                Console.WriteLine("[服务器接收]" + readStr);
                //Send
                byte[] sendBytes = System.Text.Encoding.Default.GetBytes(readStr);
                connfd.Send(sendBytes);
            }
        }
    }
}

结果

unity3d 服务器版本 unity 服务端_unity

1.5公用网和局域网

如果是校园网的局域网内,把服务端放到连接校园网的计算机上,因为只有局域网IP,所以只有局域网内的计算机可以连接上。但是有“端口映射”技术。
如果没有路由器的控制权(校园网),就要将服务端程序部署到阿里云、腾讯云等云服务器。