相关文章推荐
博学的柳树  ·  服务端主动推送数据,除了 ...·  1 年前    · 
傻傻的课本  ·  Eclipse 快捷键 | 菜鸟教程·  2 年前    · 
没有腹肌的香菇  ·  [MySQL基础]六、分组查询 - 知乎·  2 年前    · 
瘦瘦的柚子  ·  中国农业大学生物学院 副教授 王向锋·  2 年前    · 
细心的仙人球  ·  upload multiple files ...·  2 年前    · 
Code  ›  Jtro的技术分享:游戏客户端与服务器(c#)通讯_同步Socket开发者社区
客户端服务器 服务器类型 socket 游戏服务器
https://cloud.tencent.com/developer/article/1747893
苦闷的骆驼
2 年前
作者头像
张曙光
0 篇文章

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

前往专栏
腾讯云
备案 控制台
开发者社区
学习
实践
活动
专区
工具
TVP
文章/答案/技术大牛
写文章
社区首页 > 专栏 > Unity Technology > 正文

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

修改 于 2021-01-04 18:09:49
1.3K 0
举报

在游戏界,独立游戏层出不穷,但是大部分都是单机,网络游戏很少,因为不会有独立开发者自己整一个 服务器 ,除非你先去买个虚拟服务器。网络通讯一直是一个很大的学术,今天研究了一下,把服务器端的代码和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();    }
 
推荐文章
博学的柳树  ·  服务端主动推送数据,除了 WebSocket 你还能想到啥?-腾讯云开发者社区-腾讯云
1 年前
傻傻的课本  ·  Eclipse 快捷键 | 菜鸟教程
2 年前
没有腹肌的香菇  ·  [MySQL基础]六、分组查询 - 知乎
2 年前
瘦瘦的柚子  ·  中国农业大学生物学院 副教授 王向锋
2 年前
细心的仙人球  ·  upload multiple files to s3 using aws cli-掘金
2 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号