Unity3D:TCPSocket模块
服务端Socket-
上接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace YDB.TCPSocket
{public interface IServerSocket{/// <summary>/// 连接并接收数据/// </summary>void StartAccept(string receiveIP_str, string receivePort_str, Action<byte[]> action);/// <summary>/// 发送数据/// </summary>/// <param name="sendIP_Str"></param>/// <param name="sendPort_int"></param>/// <param name="data"></param>void SendPackage(byte[] data);/// <summary>/// 关闭/// </summary>void ShutDown();}
}
在实现前,因为服务器需要接收客户端,所以定义一个类来保存客户端
using System;
using System.Net;
using System.Net.Sockets;namespace YDB.TCPSocket
{public class SocketInfo{public Socket ClientSocket { get; private set; }public string ServerIP { get; private set; }public int ServerPort { get; private set; }public string ClientIP { get; private set; }public int ClientPort { get; private set; }public SocketAsyncEventArgs SocketAsyncEventArgs { get; private set; }public Action<byte[]> Callback { get; private set; }public static SocketInfo Create(Socket socket,Action<byte[]> callBack,SocketAsyncEventArgs socketAsyncEventArgs){SocketInfo socketInfo = new SocketInfo();socketInfo.Callback = callBack;socketInfo.ClientSocket = socket;IPEndPoint iPEndPoint = socket.LocalEndPoint as IPEndPoint;socketInfo.ServerIP = iPEndPoint == null ? "" : iPEndPoint.Address.ToString();socketInfo.ServerPort = iPEndPoint == null ? -1 : iPEndPoint.Port;IPEndPoint remoteEndPoint = socket.RemoteEndPoint as IPEndPoint;socketInfo.ClientIP = remoteEndPoint == null ? "" : remoteEndPoint.Address.ToString();socketInfo.ClientPort = remoteEndPoint == null ? -1 : remoteEndPoint.Port;socketInfo.SocketAsyncEventArgs = socketAsyncEventArgs;return socketInfo;}}
}
接口具体实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace YDB.TCPSocket
{public class TCPServer_Socket : IServerSocket{//接收数据容量大小private const int BufferSize = 1024;//Socketprotected Socket mSocket;//连接进来的客户端列表private Dictionary<string,SocketInfo> mClientSockets = new Dictionary<string, SocketInfo>();public TCPServer_Socket(){mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);}/// <summary>/// 关闭/// </summary>public void ShutDown(){if (mSocket == null){return;}try{mSocket.Shutdown(SocketShutdown.Both);mSocket.Close();}catch (Exception e){throw new Exception(e.ToString());}}#region 接收数据/// <summary>/// 测试时,不能以127.0.0.1测试/// </summary>/// <param name="receiveIP_str">IP</param>/// <param name="receivePort_str">Port</param>/// <param name="messageConverter">数据转换,默认Json</param>public void StartAccept(string receiveIP_str, string receivePort_str,Action<byte[]> action){if (string.IsNullOrEmpty(receiveIP_str) || string.IsNullOrEmpty(receivePort_str)){return;}int receivePort = int.Parse(receivePort_str);OnStartAccept(receiveIP_str, receivePort,action);}/// <summary>/// 接收数据/// </summary>/// <param name="eventArgs"></param>private void OnStartAccept(string receiveIP_str, int receivePort_str, Action<byte[]> action){try{IPEndPoint receiveIPEndPoint = new IPEndPoint(IPAddress.Parse(receiveIP_str), receivePort_str);Debug.Log(string.Format("绑定IP:{0}和Port:{1}", receiveIP_str, receivePort_str));mSocket.Bind(receiveIPEndPoint);mSocket.Listen(10);SocketAsyncEventArgs receiveCompletedEventArgs = new SocketAsyncEventArgs();receiveCompletedEventArgs.Completed += AcceptCompolited;receiveCompletedEventArgs.UserToken = action;OnAccept(receiveCompletedEventArgs);}catch (Exception e){throw new Exception(e.ToString());}}private void OnAccept(SocketAsyncEventArgs socketAsyncEventArgs){Debug.Log("等待接收客户端");try{bool result = mSocket.AcceptAsync(socketAsyncEventArgs);if (result == false){ProcessAccept(socketAsyncEventArgs);}}catch (Exception e){throw new Exception(e.ToString());}}/// <summary>/// 接收数据完成回调事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void AcceptCompolited(object sender, SocketAsyncEventArgs e){ProcessAccept(e);}/// <summary>/// 处理接收事件/// </summary>/// <param name="e"></param>private void ProcessAccept(SocketAsyncEventArgs e){try{//接收到的Socket还是服务器的Socket,RemoteIP/Port被赋值Socket socket = e.AcceptSocket;Action<byte[]> callback = e.UserToken as Action<byte[]>;IPEndPoint point = socket.RemoteEndPoint as IPEndPoint;Console.WriteLine("接收到了" + point.Address.ToString() + ":" + point.Port.ToString());SocketAsyncEventArgs receiveAsyncEventArgs = new SocketAsyncEventArgs();receiveAsyncEventArgs.SetBuffer(new byte[BufferSize], 0, BufferSize);receiveAsyncEventArgs.Completed += ReceiveCompleted;SocketInfo receiveSocketInfo = SocketInfo.Create(socket, callback, receiveAsyncEventArgs);receiveAsyncEventArgs.UserToken = receiveSocketInfo;OnReceive(receiveSocketInfo);mClientSockets.Add(receiveSocketInfo.ClientIP+receiveSocketInfo.ClientPort, receiveSocketInfo);Debug.Log(receiveSocketInfo.ClientIP + ":" + receiveSocketInfo.ClientPort + "已连接");e.AcceptSocket = null;OnAccept(e);}catch (Exception exception){throw new Exception(exception.ToString());}}/// <summary>/// 递归接收入口/// </summary>/// <param name="e"></param>private void OnReceive(SocketInfo socketInfo){Socket socket = socketInfo.ClientSocket;bool result = socket.ReceiveAsync(socketInfo.SocketAsyncEventArgs);if (result == false){ProcessReceive(socketInfo.SocketAsyncEventArgs);}}/// <summary>/// 接收完成/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void ReceiveCompleted(object sender, SocketAsyncEventArgs e){ProcessReceive(e);}/// <summary>/// 接收完成后处理事件/// </summary>/// <param name="e"></param>private void ProcessReceive(SocketAsyncEventArgs e){if (e.SocketError == SocketError.Success && e.BytesTransferred > 0){byte[] data = new byte[BufferSize];Buffer.BlockCopy(e.Buffer, 0, data, 0, e.BytesTransferred);e.SetBuffer(new byte[BufferSize], 0, BufferSize);SocketInfo socketInfo = e.UserToken as SocketInfo;Action<byte[]> callback = socketInfo.Callback;callback(data);OnReceive(socketInfo);}else{if (e.BytesTransferred == 0){if (e.SocketError == SocketError.Success){//客户端主动断开连接Debug.LogError("客户端主动断开连接");}else{Debug.LogError("网络异常");}}}}#endregion#region 发送数据/// <summary>/// 发送数据/// </summary>/// <param name="data"></param>public void SendPackage(byte[] data){try{foreach (var item in mClientSockets.Values){EndPoint sendEndPoint = new IPEndPoint(IPAddress.Parse(item.ClientIP), item.ClientPort);SocketAsyncEventArgs mSendAsyncEventArgs = new SocketAsyncEventArgs();mSendAsyncEventArgs.UserToken = item;mSendAsyncEventArgs.RemoteEndPoint = sendEndPoint;mSendAsyncEventArgs.Completed += SendCompolited;mSendAsyncEventArgs.SetBuffer(data, 0, data.Length);bool result = item.ClientSocket.SendToAsync(mSendAsyncEventArgs);if (result == false){ProcessSend(mSendAsyncEventArgs);}}}catch (Exception e){throw new Exception(e.ToString());}}private void SendCompolited(object sender, SocketAsyncEventArgs e){ProcessSend(e);}private void ProcessSend(SocketAsyncEventArgs async){try{Debug.Log("TCP已发送");}catch (Exception e){throw new Exception(e.ToString());}}#endregion}
}
Unity3D:TCPSocket模块相关推荐
- 【Unity3D基础教程】给初学者看的Unity教程(一):GameObject,Compoent,Time,Input,Physics...
作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点推荐.谢谢! Unity3D重要模块的类图 最近刚刚完成了一 ...
- 【Unity3D基础概念】给初学者看的Unity概览(一):GameObject,Compoent,Time,Input,Physics...
2019独角兽企业重金招聘Python工程师标准>>> 点击进入我的新博客 <p>作者:<a href="http://weibo.com/wangxua ...
- Unity常用API详解--初学必备
初学Unity3D编程,为了更加熟悉Unity常用API,根据搜集资料整理如下: 1.事件函数执行机制 2.Time类 Time.deltaTime:每一帧的时间. Time.fixedDeltaTi ...
- Unity3D 开发工具系列 日志系统:配置模块LogConfig
Unity3D 开发工具系列 日志系统:核心模块Logging Unity3D 开发工具系列 日志系统:调用封装Log Unity3D 开发工具系列 日志系统:输出模块ConsoleAppender ...
- Unity3D网络游戏实战——通用客户端模块
前言 书中说的是搭建一套商业级的客户端网络模块,一次搭建长期使用. 本章主要是完善大乱斗游戏中的网络模块,解决粘包分包.完整发送数据.心跳机制.事件分发等功能 6.1网络模块设计 核心是静态类NetM ...
- unity模块切换_(一)Unity3D模块介绍
首先点击"NEW"来创建一个新的工程 Paste_Image.png 然后给工程命名,选择好保存路径之后,点击"Create project" Paste_Im ...
- unity3d实现第一人称射击游戏之CS反恐精英(四)(子弹模块,音效特效)
实现思想 由于子弹的速度非常快,直接让子弹像现实中那样移动很容易发生'穿模'现象,所以我们用unity中的射线来实现,当用户点击鼠标左键的时候,播放开枪动画,火花特效,开火音效,枪口发射一条射线,检测 ...
- vue项目接入unity3D模块并进行数据通信
一.添加unity工程 unity工程师会提供一个前端可使用的包,将其放在vue项目的public下,我这里以unity文件夹命名 二.在项目中创建iframe标签并引入index.html文件 &l ...
- Unity3D编辑器操作技巧37-粒子系统-Lights-Trails-CustomData-Renderer模块
- Unity导出apk出现的问题,JDK,Android SDK,NDK,无“安装模块”
导出apk失败 使用unity导出apk文件,会出现提示:需要合适版本的JDK.Android SDK和Android NDK,要找到.下载和安装好合适的版本非常耗费时间, 网上很多教程指出可以直接在 ...
最新文章
- 关于Scala递归返回参数的问题
- 修改maven本地仓库位置
- esp8266接7735_基于8266的ESPEASY固件接入HASS的教程(可无脑接入各类传感...
- Java基础学习总结(43)——Java8 Lambda揭秘
- 案例-旋转木马(CSS3)
- 最顶尖的12个IT技能
- 周立功USBCAN资料分享
- 使用VsCode搭建Vue开发环境
- 雨过天晴电脑保护系统校园版
- addr2line命令使用
- Window环境MatConvNet安装
- ImportError: cannot import name 'imsave' from 'scipy.misc' (C:\Users\DELL\AppData\Roaming\Python\Pyt
- 16年,平凡而又收获的一年,为什么说Flutter让移动开发变得更好
- dxf解析python_Python 读取DXF文件
- cocos2dx-基本动画制作
- trim函数去除空格(所有空格,前后,前,后)以及字母大小写切换
- D3.js从入门指南
- C/C++编程笔记:C++中的isspace()及其在计算空格字符中的应用
- android 神气插件 自动补全tabnine
- 成都计算机博士点,2017学位授权审核结果公示!快看四川高校新增哪些博士点?...