征服Unity3dunity3D技术分享unity编程技术

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

2017-11-11  本文已影响114人  UnityPlane

在游戏界,独立游戏层出不穷,但是大部分都是单机,网络游戏很少,因为不会有独立开发者自己整一个服务器,除非你先去买个虚拟服务器。网络通讯一直是一个很大的学术,今天研究了一下,把服务器端的代码和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现在怎么发图片请告诉我一下。谢啦

上一篇下一篇

猜你喜欢

热点阅读