参考:《Unity3D网络游戏实战》

服务端代码

连接管理

用于对客户端的连接进行抽象

public class Conn
{public const int BUFFER_SIZE = 1024;//Socketpublic Socket socket;public bool isUse = false;//buffpublic byte[] readBuffer = new byte[BUFFER_SIZE];public int bufferCount = 0;public Conn(){readBuffer = new byte[BUFFER_SIZE];}public void Init(Socket socket){this.socket = socket;isUse = true;bufferCount = 0;}public int BufferRemain(){return BUFFER_SIZE - bufferCount;}public string GetAddress(){if (!isUse){return "无法获取地址";}return socket.RemoteEndPoint.ToString();}public void Close(){if (socket != null){Console.WriteLine("Close");socket.Close();isUse = false;}}
}

服务器类

成员

public class Server
{//监听public Socket listenfd;//客户端地址public Conn[] conns;//最大连接数public int maxConn = 50;...
}

获取可用端口

public int GetConn()
{if (conns == null) return -1;for (int i = 0; i < maxConn; i++){if (conns[i] == null){conns[i] = new Conn();return i;}else if (!conns[i].isUse){conns[i].isUse = true;return i;}}return -1;
}

启动

public void Start(string host, int port)
{conns = new Conn[maxConn];for (int i = 0; i < maxConn; i++){conns[i] = new Conn();}//Socketlistenfd = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//BindIPAddress IPAddress = IPAddress.Parse(host);IPEndPoint endpoint = new IPEndPoint(IPAddress, port);listenfd.Bind(endpoint);//Listenlistenfd.Listen(maxConn);//Acceptlistenfd.BeginAccept(AccepCb, null);Console.WriteLine("Server Enable", listenfd.LocalEndPoint);
}

Accept回调

private void AccepCb(IAsyncResult ar)
{try{Socket connfd = listenfd.EndAccept(ar);int index = GetConn();if (index < 0){connfd.Close();Console.WriteLine("too many connection");return;}Conn conn = conns[index];conn.Init(connfd);Console.WriteLine("Accepted");connfd.BeginReceive(conn.readBuffer, 0, conn.readBuffer.Length, SocketFlags.None, ReceiveCb, conn);listenfd.BeginAccept(AccepCb, null);}catch (Exception e){Console.WriteLine("AcceptCb Fail : " + e.Message);}}

Receive回调

private void ReceiveCb(IAsyncResult ar)
{Conn conn = (Conn)ar.AsyncState;try{int count = conn.socket.EndReceive(ar);if (count <= 0){Console.WriteLine($"Received [{conn.GetAddress()}] Connection Close");conn.Close();return;}//数据处理string str = System.Text.Encoding.UTF8.GetString(conn.readBuffer, 0, count);Console.WriteLine($"Received [{conn.GetAddress()}] : {str}");byte[] bytes = System.Text.Encoding.UTF8.GetBytes($"[{conn.GetAddress()}] : {str}");//广播foreach (Conn conn_ in conns){if (conn_ == null || !conn_.isUse) continue;conn_.socket.Send(bytes);Console.WriteLine($"Send to [{conn_.GetAddress()}]");}//继续接收conn.socket.BeginReceive(conn.readBuffer, conn.bufferCount, conn.readBuffer.Length, SocketFlags.None, ReceiveCb, conn);}catch (Exception e){Console.WriteLine("ReceiveCb Fail : " + e.Message);}
}

客户端

成员

    //IP与端口public TMP_InputField hostInput;public TMP_InputField portInput;//文本public TMP_Text recvText;public TMP_Text clientText;//输入框public TMP_InputField textInput;//Socket and bufferSocket socket;const int BUFFER_SIZE = 1024;byte[] readBuffer = new byte[BUFFER_SIZE];//输入的文本string receivedText;

与服务器连接并接收消息

public void Connection()
{recvText.text = "";//socketsocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//Connectsocket.Connect(hostInput.text, int.Parse(portInput.text));clientText.text = "Client Address " + socket.LocalEndPoint.ToString();//Receivesocket.BeginReceive(readBuffer, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCb, null);
}

回调函数

注意:不能在回调函数中对Unity组件进行操作,因为回调函数不在主线程中

private void ReceiveCb(IAsyncResult ar)
{try{//数据大小int recvSize = socket.EndReceive(ar);//数据处理string recvStr = System.Text.Encoding.UTF8.GetString(readBuffer, 0, recvSize);if (recvStr.Length > 300) recvStr = "[Text too long]";receivedText += recvStr + "\n";//继续接收socket.BeginReceive(readBuffer, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCb, null); }catch (Exception e){Debug.Log(e.Message);receivedText = "Connection Close";socket.Close();}
}

发送消息

public void Send()
{string str = textInput.text;if (str == ""){textInput.DeactivateInputField();return;}textInput.text = "";textInput.ActivateInputField();byte[] bytes = System.Text.Encoding.UTF8.GetBytes(str);try{socket.Send(bytes);}catch (Exception e){Debug.Log(e.Message);socket.Close();}
}

Unity 网络编程入门相关推荐

  1. 脑残式网络编程入门(三):HTTP协议必知必会的一些知识

    为什么80%的码农都做不了架构师?>>>    本文原作者:"竹千代",原文由"玉刚说"写作平台提供写作赞助,原文版权归"玉刚说&q ...

  2. 脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

    转自即时通讯网:http://www.52im.net/ 1.引言 网络编程中TCP协议的三次握手和四次挥手的问题,在面试中是最为常见的知识点之一.很多读者都知道"三次"和&quo ...

  3. BIO,Socket网络编程入门代码示例,NIO网络编程入门代码示例,AIO 网络编程

    BIO,Socket网络编程入门代码示例 1.BIO服务器端程序 package cn.itcast.bio;import java.io.InputStream; import java.io.Ou ...

  4. Day14.网络编程入门及其应用

    网络编程入门及其应用 文章目录 网络编程入门及其应用 前言 一. 网络编程的入门 1.1 计算机网络基础 1.2 计算机网络发展史 1.3 TCP/IP模型 1.4 网络应用模式 二. 基于HTTP协 ...

  5. Day14:网络编程入门

    网络编程入门 计算机网络基础 计算机网络是独立自主的计算机互联而成的系统的总称,组建计算机网络最主要的目的是实现多台计算机之间的通信和资源共享.今天计算机网络中的设备和计算机网络的用户已经多得不可计数 ...

  6. P41 网络编程入门

    P41 网络编程入门 1.软件结构 2.网络通信协议 3.协议分类 4.网络编程三要素 4.1 协议 4.2 IP地址 4.3 端口号 系统:Win10 Java:1.8.0_333 IDEA:202 ...

  7. TCP原理,Socket与网络编程入门

    TCP原理,Socket与网络编程入门 开篇 从互联网的诞生以来,网络程序逐渐普及.计算机网络将各个计算机连接到一起使它们可以通信.在现代,网络已成为我们十分重要的一部分.这次不搞些费脑子的东西,就让 ...

  8. Linux网络编程 入门

    Linux网络编程入门 (转载) (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍 客户端和服务端          网络程序和普通的程序有一个最大的区别是网络程序是由两个 ...

  9. 脑残式网络编程入门(八):你真的了解127.0.0.1和0.0.0.0的区别?

    本文由"小姐姐养的狗"原创发布于"小姐姐味道"公众号,原题<127.0.0.1和0.0.0.0地址的区别>,收录时有优化和改动.感谢原作者的分享. ...

最新文章

  1. 转《刘润的数字化家庭》
  2. ImageView、Bitmap的属性android:scaleType
  3. getRequestDispatcher()与sendRedirect()的区别
  4. service mysqld start,Failed to start mysqld.service: Access denied
  5. [初级]Java命令学习系列(六)——jinfo
  6. centos ping不通百度 ping不通外网
  7. 一种简单、实用的测量程序运行时间的方法
  8. C语言fscanf函数了解
  9. 正则只能小于0负数_2019–2020学年七年级数学期末考试考点之正数与负数考点详解...
  10. 用java统计任一书名次数_Java入门第三季 借书系统源代码 加入了限制重输次数 欢迎指教交流...
  11. 【SpringMVC 笔记】结果跳转、数据处理、乱码问题
  12. pytorch_LSTM预测股票行情
  13. 五月康乃馨,爱心献父母---母亲节快乐
  14. 黑群晖二合一已损毁_黑群晖二合一ghost安装教程(蜜獾超存可用)
  15. python编程招生海报_怎么用ps做招生海报
  16. 牛客小白月赛2 J.美
  17. ubuntu默认壁纸位置
  18. matlab实现简单清浊音检测
  19. 【Java】如何检测、替换4个字节的utf-8编码(此范围编码包含emoji表情)
  20. 前端关于Recat面试题(九)

热门文章

  1. QQ无法访问个人文件夹,修复失败问题
  2. 连接共享打印机提示【操作失败,错误为0x0000011b】
  3. Cy5-MAL,Cy5-马来酰亚胺,1437796-65-0,1437872-46-2
  4. Hadoop安装准备
  5. 何为集中式版本控制系统与分布式版本控制系统?
  6. js的exports
  7. 徐宗本院士:智能制造的大数据机遇与挑战
  8. python编写代码求圆的面积_【Python】求圆的面积,书上的代码可执行却是0,不知道为什么...
  9. 如果不坚持,到哪里都是放弃
  10. MySql计算两个日期的时间差函数