[Unity Socket]在Unity中如何实现异步Socket通信技术
在刚刚开发Unity项目的过程中,需要用到即时通信功能来完成服务器与客户端自定义的数据结构封装。
现在将部分主要功能的实现代码抽取出来实现了可以异步Socket请求的技术Demo。
客户端脚本ClientScript
/// <summary>
/// Client Script.
/// Created By 蓝鸥3G 2014.08.23
/// </summary> using UnityEngine;
using System.Collections; public class ClientScript: MonoBehaviour {
string msg = "";
// Use this for initialization LOSocket client;
void Start () {
client = LOSocket.GetSocket(LOSocket.LOSocketType.CLIENT);
client.InitClient ("127.0.0.1", , ((string content) => {
//收到服务器的回馈信息
}));
} void OnGUI() {
msg = GUI.TextField(new Rect(, , , ), msg);
if(GUI.Button(new Rect(, , , ), "Send"))
{ client.SendMessage (msg);
}
}
}
服务器端脚本
/// <summary>
/// Server Script.
/// Created By 蓝鸥3G 2014.08.23
/// </summary>
///
///
using UnityEngine;
using System.Collections; public class ServerScript : MonoBehaviour { private string receive_str;
LOSocket server;
// Use this for initialization
void Start ()
{
server = LOSocket.GetSocket(LOSocket.LOSocketType.SERVER);
//初始化服务器
server.InitServer((string content) => {
receive_str = content;
});
} void OnGUI()
{
if (receive_str != null)
{
GUILayout.Label (receive_str);
}
}
}
LOSocket框架
/// <summary>
/// LOSocket.
/// Created By 蓝鸥3G 2014.08.23
/// </summary>
///
///
using UnityEngine;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Text; //收到消息后的委托回调
public delegate void ReceiveCallBack(string content); public class LOSocket{ //可以创建的Socket端口类型
public enum LOSocketType
{
CLIENT = ,
SERVER = ,
}
#region --------取消构造器
private LOSocket()
{
} #endregion #region --------公共代码
//通过静态方法获取不同的端口类型
public static LOSocket GetSocket(LOSocket.LOSocketType type)
{
LOSocket socket = null; switch (type) {
case LOSocketType.CLIENT:
{
//创建一个新的客户端
socket = new LOSocket ();
break;
}
case LOSocketType.SERVER:
{
//获取服务端
socket = GetServer ();
break;
}
} return socket;
} #endregion
#region --------客户端部分代码
private Socket clientSocket; //声明客户端收到服务端返回消息后的回调委托函数
private ReceiveCallBack clientReceiveCallBack;
//用来存储服务端返回的消息数据
byte[] Buffer = new byte[]; //初始化客户端Socket信息
public void InitClient(string ip,int port,ReceiveCallBack ccb)
{
this.clientReceiveCallBack = ccb;
this.clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPAddress address = IPAddress.Parse (ip);
IPEndPoint ep = new IPEndPoint (address, port); this.clientSocket.Connect(ep);
//开始异步等待接收服务端消息
this.clientSocket.BeginReceive (Buffer, , Buffer.Length, SocketFlags.None, new System.AsyncCallback(ReceiveFromServer), this.clientSocket);
} //收到服务端返回消息后的回调函数
void ReceiveFromServer(System.IAsyncResult ar)
{
//获取当前正在工作的Socket对象
Socket worker = ar.AsyncState as Socket;
int ByteRead=;
try
{
//接收完毕消息后的字节数
ByteRead = worker.EndReceive(ar);
}
catch (System.Exception ex)
{
this.clientReceiveCallBack (ex.ToString ());
}
if (ByteRead > )
{
string Content = Encoding.Default.GetString (Buffer);
//通过回调函数将消息返回给调用者
this.clientReceiveCallBack (Content);
}
//继续异步等待接受服务器的返回消息
worker.BeginReceive(Buffer, , Buffer.Length, SocketFlags.None, new System.AsyncCallback(ReceiveFromServer), worker);
} //客户端主动发送消息
public void SendMessage(string message)
{
if (message == null)
return; message += "\r\n";
byte[] sendData = Encoding.UTF8.GetBytes (message); //异步发送消息请求
clientSocket.BeginSend (sendData, , sendData.Length, SocketFlags.None, new System.AsyncCallback (SendToServer), clientSocket);
}
//发送消息结束的回调函数
void SendToServer(System.IAsyncResult ar)
{
Socket worker = ar.AsyncState as Socket;
worker.EndSend (ar);
} #endregion #region -------服务器部分代码
//服务器端收到消息的存储空间
byte[] ReceiveBuffer = new byte[];
//服务器收到消息后的回调委托
private ReceiveCallBack callback; //单例模式
private static LOSocket serverSocket;
private static LOSocket GetServer() {
if (serverSocket == null) {
serverSocket = new LOSocket();
}
return serverSocket;
} //初始化服务器信息
public void InitServer(ReceiveCallBack cb) {
this.callback = cb;
// 1.
Socket server_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 2.
IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, );
// 3.
server_socket.Bind(endPoint);
// 4.
server_socket.Listen();
// 5.开始异步等待客户端的请求链接
server_socket.BeginAccept (new System.AsyncCallback (Accept), server_socket); this.callback ("开启服务器" + endPoint.ToString());
} //接受到客户端的链接请求后的回调函数
void Accept(System.IAsyncResult ar){
//获取正在工作的Socket对象
Socket socket = ar.AsyncState as Socket;
//存储异步操作的信息,以及用户自定义的数据
Socket worker = socket.EndAccept(ar); SocketError error; //开始异步接收客户端发送消息内容
worker.BeginReceive (ReceiveBuffer, , ReceiveBuffer.Length, SocketFlags.None, new System.AsyncCallback (Receive), worker);
//继续异步等待新的客户端链接请求
socket.BeginAccept(new System.AsyncCallback(Accept), socket); }
//服务端收到客户端的消息后的回调函数
void Receive(System.IAsyncResult ar)
{
//获取正在工作的Socket对象
Socket worker = ar.AsyncState as Socket;
int ByteRead=;
try
{
ByteRead = worker.EndReceive(ar);
}
catch (System.Exception ex)
{
this.callback (ex.ToString ());
}
if (ByteRead > )
{
string Content = Encoding.Default.GetString (ReceiveBuffer);
this.callback (Content);
}
//继续异步等待客户端的发送消息请求
worker.BeginReceive(ReceiveBuffer, , ReceiveBuffer.Length, SocketFlags.None, new System.AsyncCallback(Receive), worker);
}
#endregion
}
[Unity Socket]在Unity中如何实现异步Socket通信技术的更多相关文章
- Unity中进程间通信——使用异步Socket
开发Unity项目过程中,即时通信功能来完成服务器与客户端自定义的数据结构封装. 如果要序列化和数据封装参考:Unity3D之C#用Socket传数据包 蓝鸥3G封装的类 客户端脚本ClientScr ...
- socket网络编程中的同步,异步,阻塞式,非阻塞式,有何联系与区别?
一.举个打电话的例子: 阻塞 block 是指,你拨通某人的电话,但是此人不在,于是你拿着电话等他回来,其间不能再用电话.同步大概和阻塞差不多. 非阻塞 nonblock 是指,你拨通 ...
- Unity3D中简单的C#异步Socket实现
Unity3D中简单的C#异步Socket实现 简单的异步Socket实现..net框架自身提供了很完善的Socket底层.笔者在做Unity3D小东西的时候需要使用到Socket网络通信.于是决定自 ...
- 《Unity 3D游戏客户端基础框架》多线程异步 Socket 框架构建
引言: 之前写过一个 demo 案例大致讲解了 Socket 通信的过程,并和自建的服务器完成连接和简单的数据通信,详细的内容可以查看 Unity3D -- Socket通信(C#).但是在实际项目应 ...
- 【Unity技巧】Unity中的优化技术
http://blog.csdn.net/candycat1992/article/details/42127811 写在前面 这一篇是在Digital Tutors的一个系列教程的基础上总结扩展而得 ...
- C# Unity游戏开发——Excel中的数据是如何到游戏中的 (二)
本帖是延续的:C# Unity游戏开发——Excel中的数据是如何到游戏中的 (一) 上个帖子主要是讲了如何读取Excel,本帖主要是讲述读取的Excel数据是如何序列化成二进制的,考虑到现在在手游中 ...
- C# Unity游戏开发——Excel中的数据是如何到游戏中的 (三)
本帖是延续的:C# Unity游戏开发——Excel中的数据是如何到游戏中的 (二) 前几天有点事情所以没有继续更新,今天我们接着说.上个帖子中我们看到已经把Excel数据生成了.bin的文件,不过其 ...
- 【Unity编程】Unity中关于四元数的API详解
本文为博主原创文章,欢迎转载,请保留出处:http://blog.csdn.net/andrewfan Unity中关于四元数的API详解 Quaternion类 Quaternion(四元数)用于计 ...
- C# Unity游戏开发——Excel中的数据是如何到游戏中的 (四)2018.4.3更新
本帖是延续的:C# Unity游戏开发--Excel中的数据是如何到游戏中的 (三) 最近项目不算太忙,终于有时间更新博客了.关于数据处理这个主题前面的(一)(二)(三)基本上算是一个完整的静态数据处 ...
随机推荐
- 转 Apache Ant 实现自动化部署
Apache Ant 实现自动化部署 Apache Ant 实现自动化部署 http://www.netkiller.cn/journal/java.ant.html Mr. Neo Chen (陈景 ...
- md5 加密模板
public class MD5Util { public static String getDigestedPassword(String password) throws NoSuchAlgori ...
- 【威佐夫博奕】 betty定理 poj 1067
Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后 ...
- Sockets
Sockets time limit per test 2 seconds memory limit per test 256 megabytes input standard input outpu ...
- java 数据结构 队列的实现
java 数据结构队列的代码实现,可以简单的进行入队列和出队列的操作 /** * java数据结构之队列的实现 * 2016/4/27 **/ package cn.Link; import java ...
- 初探JavaScript魅力(四)
选项卡 <title>无标题文档</title> <style> #div1 .active{background:#FF0;} #div1 div{width:2 ...
- springMVC下载文件前修改文件名字
很多时候,为了方便,下载文件其实就直接写了一个文件在服务器上面的路径,然后直接点击一个这个地址,浏览器就自然而然的开始下载了. 但是这次项目需要在文件下载之前修改文件的名字,也就是说,服务器上文件的名 ...
- java文件处理之压缩,分割
http://blog.csdn.net/ycg01/article/details/1366648 java文件处理之压缩,分割 标签: javaexceptionimportnullbytefil ...
- jquery选择器 之 获取父级元素、同级元素、子元素(转)
一.获取父级元素 1. parent([expr]): 获取指定元素的所有父级元素 <div id="par_div"><a id="href_fir& ...
- Nginx反向代理配置文件
server { listen ; server_name ; root E:/Upays/public/; index index.php index.html; log_not_found off ...