专栏首页Unity TechnologyJtro的技术分享:游戏客户端与服务器(c#)通讯_同步Socket

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

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

然后运行时的截图

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

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

下次把这个功能实现

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Jtro的技术分享:c#中的线程互斥

    通过多线程,c#能够并行执行代码。每一个线程都有它独立的执行路径,所有的线程都能够访问共有的变量。下面的例子说明这个问题:

    LittleU
  • 读取JSON文件 如何在Unity中读取Json文件中的数据

    Josn是一种轻量级的数据交换格式,JSON能够描述四种简单的类型(字符串、数字、布尔值及null)和两种结构化类型(对象及数组),在Unity里经常用Json...

    LittleU
  • 【玩转腾讯云】Unity接入游戏联机对战引擎(04)

    那么现在呢,给大家讲一下网络里面的基础知识,什么叫通讯协议,但是我说的通讯协议不是百度上搜索的TCP/IP,UDP的这种,我说的通讯协议是指你和其他客户端之间的...

    LittleU
  • 通俗地讲述10种常用的软件架构模式

    有没有想过如何设计大型企业级系统? 在开始开发主要软件之前,我们必须选择一个合适的架构来为我们提供所需的功能和质量等属性。 因此,在将它们应用于我们的设计之前,...

    猿哥
  • 大数据使“定制”新的经济指标成为可能

    大数据文摘
  • 别乱提交代码了,看下大厂 Git 提交规范是怎么做的!

    git是现在市面上最流行的版本控制工具,书写良好的commit message能大大提高代码维护的效率。但是在日常开发中由于缺少对于commit message...

    搜云库技术团队
  • 别乱提交代码了,看下大厂 Git 提交规范是怎么做的!

    现在市面上比较流行的方案是约定式提交规范(Conventional Commits),它受到了Angular提交准则的启发,并在很大程度上以其为依据。约定式提交...

    Erwin
  • 别乱提交代码了,看下大厂 Git 提交规范是怎么做的!

    现在市面上比较流行的方案是约定式提交规范(Conventional Commits),它受到了Angular提交准则的启发,并在很大程度上以其为依据。约定式提交...

    芋道源码
  • 程序员都该懂点 HTTP

    HTTP 全称是 HyperText Transfer Protocal ,即:超文本传输协议,从 1990 年开始就在 WWW 上广泛应用,是现今在 WWW ...

    developerHaoz
  • Linux应急响应(三):挖矿病毒

    随着虚拟货币的疯狂炒作,利用挖矿脚本来实现流量变现,使得挖矿病毒成为不法分子利用最为频繁的攻击方式。新的挖矿攻击展现出了类似蠕虫的行为,并结合...

    Bypass

扫码关注云+社区

领取腾讯云代金券

,,