服务端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模块相关推荐

  1. 【Unity3D基础教程】给初学者看的Unity教程(一):GameObject,Compoent,Time,Input,Physics...

    作者:王选易,出处:http://www.cnblogs.com/neverdie/  欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点推荐.谢谢! Unity3D重要模块的类图 最近刚刚完成了一 ...

  2. 【Unity3D基础概念】给初学者看的Unity概览(一):GameObject,Compoent,Time,Input,Physics...

    2019独角兽企业重金招聘Python工程师标准>>> 点击进入我的新博客 <p>作者:<a href="http://weibo.com/wangxua ...

  3. Unity常用API详解--初学必备

    初学Unity3D编程,为了更加熟悉Unity常用API,根据搜集资料整理如下: 1.事件函数执行机制 2.Time类 Time.deltaTime:每一帧的时间. Time.fixedDeltaTi ...

  4. Unity3D 开发工具系列 日志系统:配置模块LogConfig

    Unity3D 开发工具系列 日志系统:核心模块Logging Unity3D 开发工具系列 日志系统:调用封装Log Unity3D 开发工具系列 日志系统:输出模块ConsoleAppender ...

  5. Unity3D网络游戏实战——通用客户端模块

    前言 书中说的是搭建一套商业级的客户端网络模块,一次搭建长期使用. 本章主要是完善大乱斗游戏中的网络模块,解决粘包分包.完整发送数据.心跳机制.事件分发等功能 6.1网络模块设计 核心是静态类NetM ...

  6. unity模块切换_(一)Unity3D模块介绍

    首先点击"NEW"来创建一个新的工程 Paste_Image.png 然后给工程命名,选择好保存路径之后,点击"Create project" Paste_Im ...

  7. unity3d实现第一人称射击游戏之CS反恐精英(四)(子弹模块,音效特效)

    实现思想 由于子弹的速度非常快,直接让子弹像现实中那样移动很容易发生'穿模'现象,所以我们用unity中的射线来实现,当用户点击鼠标左键的时候,播放开枪动画,火花特效,开火音效,枪口发射一条射线,检测 ...

  8. vue项目接入unity3D模块并进行数据通信

    一.添加unity工程 unity工程师会提供一个前端可使用的包,将其放在vue项目的public下,我这里以unity文件夹命名 二.在项目中创建iframe标签并引入index.html文件 &l ...

  9. Unity3D编辑器操作技巧37-粒子系统-Lights-Trails-CustomData-Renderer模块

  10. Unity导出apk出现的问题,JDK,Android SDK,NDK,无“安装模块”

    导出apk失败 使用unity导出apk文件,会出现提示:需要合适版本的JDK.Android SDK和Android NDK,要找到.下载和安装好合适的版本非常耗费时间, 网上很多教程指出可以直接在 ...

最新文章

  1. 关于Scala递归返回参数的问题
  2. 修改maven本地仓库位置
  3. esp8266接7735_基于8266的ESPEASY固件接入HASS的教程(可无脑接入各类传感...
  4. Java基础学习总结(43)——Java8 Lambda揭秘
  5. 案例-旋转木马(CSS3)
  6. 最顶尖的12个IT技能
  7. 周立功USBCAN资料分享
  8. 使用VsCode搭建Vue开发环境
  9. 雨过天晴电脑保护系统校园版
  10. addr2line命令使用
  11. Window环境MatConvNet安装
  12. ImportError: cannot import name 'imsave' from 'scipy.misc' (C:\Users\DELL\AppData\Roaming\Python\Pyt
  13. 16年,平凡而又收获的一年,为什么说Flutter让移动开发变得更好
  14. dxf解析python_Python 读取DXF文件
  15. cocos2dx-基本动画制作
  16. trim函数去除空格(所有空格,前后,前,后)以及字母大小写切换
  17. D3.js从入门指南
  18. C/C++编程笔记:C++中的isspace()及其在计算空格字符中的应用
  19. android 神气插件 自动补全tabnine
  20. 成都计算机博士点,2017学位授权审核结果公示!快看四川高校新增哪些博士点?...

热门文章

  1. Revit二次开发——新建墙类型
  2. 傅里叶变换matlab学习笔记
  3. echart的基本使用方法
  4. EDEM颗粒堆积fluent meshing网格生成
  5. SpringMvc工作原理学习总结
  6. 2022电工(初级)操作证考试题库及模拟考试
  7. 点击查看详情显示更多布局
  8. 深度卷积神经网络结构演变
  9. Linux: sctp 实例
  10. 20210706_IEEEDataPort免费订阅