美文网首页征服Unity3dunity3D技术分享unity编程技术
Jtro的技术分享:游戏客户端与服务器(c#)通讯_同步Sock

Jtro的技术分享:游戏客户端与服务器(c#)通讯_同步Sock

作者: UnityPlane | 来源:发表于2017-11-11 17:59 被阅读114次

    在游戏界,独立游戏层出不穷,但是大部分都是单机,网络游戏很少,因为不会有独立开发者自己整一个服务器,除非你先去买个虚拟服务器。网络通讯一直是一个很大的学术,今天研究了一下,把服务器端的代码和unity作为客户端的代码写了下来。可能还不完善大家凑合看,有什么问题可以私我。给大家一个网络编程的思考。

    废话不多说,直接上代码,首先是服务器端的,这个不需要打开unity,直接打开mono或者是vs直接输入代码在控制台运行就行,在这里,围栏方便大家调试我把源码贴出来。大家复制就行了。

    ```

    /*

    * 脚本功能:服务器

    * 作者      :张曙光

    * 日期      :2017.11.11

    */

    using System;

    using System.Net;                                                //引入命名空间

    using System.Net.Sockets;                                        //引入命名空间

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    using System.Threading.Tasks;

    namespace Server

    {

    class Program

    {

    static void Main(string[] args)

    {

    Console.WriteLine("这是一个服务器,你相信吗?");

    //Socket  套接字

    Socket listenfd = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    /*

    *  现在解释上面的一行代码,功能是实例了一个套接字,它的3个参数分别代表了地址簇、套接字类型和协议

    *  地址簇指明用的是IPv4还是用的是IPv6,

    *  SocketType指的是套接字的类型,游戏开发中用的stream居多

    *    ProtocolType指明使用的协议,如你所见,用的是TCP协议

    */

    //Bind

    IPAddress ipAdr = IPAddress.Parse("127.0.0.1");

    IPEndPoint ipEp = new IPEndPoint(ipAdr ,1234);

    listenfd.Bind(ipEp);

    /*

    *  listenfd.Bind(ipEp)将给listenfd套接字绑定IP和端口。在这里是绑定的是本地地址127.0.0.1和1234号端口

    *  127.0.0.1是回送地址,指的是本地机,一般用来测试,当然你可以设置成另外一台机的ip地址,然后在2台电

    *  脑上分别运行客户端和服务器端

    */

    //Listen

    listenfd.Listen(0);

    Console.WriteLine("[ 服务器 ] 启动成功");

    /*

    * listenfd.Listen(0)开启监听器,等待客户端连接,参数backlog指定队列中最多可容纳多少人连接,0表示不限制

    */

    while (true)

    {

    //Accept

    Socket connfd = listenfd.Accept();

    Console.WriteLine("[服务器] Accept");

    /*

    * 开启监听器后,服务器开始调用listenfd.Accept()接收客户端连接。本案例使用的所有Socket方法都是“阻塞”

    * 方法,也就是说,如果一直没有客户点连接进来的话,服务器的程序会一直卡在listenfd.Accpect()处,不往

    * 下执行,直到客户端连接之后Accpet返回一个新的客户端的Socket,对于服务器来说它有一个监听的Socket(案

    * 例中的listenfd)用来接收Accpet客户端的连接,对于每一个客户端来说,还有一个专门的Socket(案例中的Connfd)

    * 用来处理该客户端的数据

    */

    //Recv

    byte[] readBuff = new byte[1024];

    int count = connfd.Receive(readBuff);

    string str = System.Text.Encoding.UTF8.GetString(readBuff, 0, count);

    Console.WriteLine("[ 服务器接收 ]" +str);

    /*

    * 服务器通过connfd.Receive接收客户端数据,receive也是阻塞的方法,没有接收到客户端数据时,程序卡在Receive

    * 处,不会向下执行,Receive带有一个byte[]类型的参数,它将储存接收到的数据,Receive的返回值则指明接收到的

    * 数据长度之后,用string str = System.Text.Encoding.UTF8.GetString(readBuff, 0, count);这段代码将byte[]数

    * 组转化为字符串显示在屏幕上

    */

    //Send

    byte[] bytes = System.Text.Encoding.Default.GetBytes(" Serv echo " + str);

    connfd.Send(bytes);

    /*

    * 服务器通过Connfd.Send发送数据,它接收一个byte[]类型的参数指明要发送的内容,Send的返回值指明发送的数据长

    * 度(案例中没有),服务器程序用System.Text.Encoding.Default.GetBytes(" Serv echo " + str)把字符串转换成

    * byte[]数组,然后发送给客户端。

    */

    }

    }

    }

    }

    ```

    注释已经写的很明白了。

    这是运行的图:

    服务器运行的                                        时候                                        客户端还没链接

    那么接下来就是unity客户端的了

    首先新建一个unity空工程,我的unity版本是2017.2.0.f3的版本,所以2017.2.0.f3版本之下的版本复制粘贴都没问题。

    新建画布添加组件,和我这个差不多就行。排版自己排就行。

    组件                                        H                                        ierarchy                                        视图 Game                                                                                                                        视图

    新建一个脚本,叫NET,这里同样贴出代码,方便大家复制粘贴调试。

    ```

    //初创日期  :2017.11.11

    //脚本功能  :客户端

    //脚本挂载在:    不需要挂在任何物体上

    //作者:    Jtro//第一次修改:

    /**/

    using System.Collections;

    using System.Collections.Generic;using UnityEngine;using System.Net;                  //引入命名空间

    using System.Net.Sockets;          //引入命名空间

    using UnityEngine.UI;public class net : MonoBehaviour {    Socket socket;                  //与服务器端的套接字

      public InputField HostInput;    //服务器端的ip地址

        public InputField PortInput;    //服务器端的端口,其实在服务器那块7777端口也能用。

        public Text RecvText;          //服务器收到的信息

        public Text ClientText;        //客户端的信息

        const int BUFFER_SIZE = 1024;  //接收缓冲区

      byte[] readBuff = new byte[BUFFER_SIZE];

        ////// 按钮点击事件

    ///public void Btn_Connetion()

      {        //Socket 

        socket = new Socket(AddressFamily .InterNetwork,SocketType.Stream ,ProtocolType.Tcp);     

    //Connect   

      string host = HostInput.text;        string strport = PortInput.text;        int port = int .Parse(strport);        socket.Connect(host ,port);        ClientText.text = "客户端地址 " + socket.LocalEndPoint.ToString();   

      //Send   

      string str = "HELLO , I am Jtro.";     

    string time = System.DateTime.Now.ToString();   

    byte[] bytes = System.Text.Encoding.Default.GetBytes(str+ "  "+time);   

    socket.Send(bytes);   

      //Recv     

    int count = socket.Receive(readBuff);

    str = System.Text.Encoding.UTF8.GetString(readBuff, 0, count);

    RecvText.text = str;        //Close        socket.Close();    }

    // Use this for initialization

    void Start () {}

    // Update is called once per framevoid Update () {

    }

    }

    ```

    然后运行时的截图

    输入                                                                                                                        服务器地址                                        点击连接服务器

    好了这样就行了,可以看到发送的信息,那么,如果是要写一个及时聊天系统该如何写呢?

    下次把这个功能实现

    OK,感谢简书,感谢读完的你。

    然后现在的简书MARKDOEN不能发图片了吗,以前是可以的,现在这个这是用富文本写的,所以代码没有被排版,有谁知道Markdown现在怎么发图片请告诉我一下。谢啦

    相关文章

      网友评论

      • UnityPlane:后续的网络编程教程不再投稿。直接到我的简书里看

      本文标题:Jtro的技术分享:游戏客户端与服务器(c#)通讯_同步Sock

      本文链接:https://www.haomeiwen.com/subject/ufzwmxtx.html