├── u3d ├── ProjectSettings │ ├── ProjectVersion.txt │ ├── TagManager.asset │ ├── AudioManager.asset │ ├── InputManager.asset │ ├── NavMeshAreas.asset │ ├── TimeManager.asset │ ├── DynamicsManager.asset │ ├── EditorSettings.asset │ ├── NetworkManager.asset │ ├── ProjectSettings.asset │ ├── QualitySettings.asset │ ├── GraphicsSettings.asset │ ├── Physics2DSettings.asset │ ├── ClusterInputManager.asset │ ├── EditorBuildSettings.asset │ └── UnityConnectSettings.asset └── Assets │ ├── Example.meta │ ├── Source.meta │ ├── Source │ ├── Socket.meta │ ├── Socket │ │ ├── Common.meta │ │ └── Common │ │ │ ├── NetQueue.cs.meta │ │ │ ├── PackBase.cs.meta │ │ │ ├── NetEncrypt.cs.meta │ │ │ ├── PackBase.cs │ │ │ ├── NetEncrypt.cs │ │ │ └── NetQueue.cs │ ├── StreamBuffer.cs.meta │ ├── SwitchQueue.cs.meta │ ├── TCPSession.cs.meta │ ├── SwitchQueue.cs │ ├── StreamBuffer.cs │ └── TCPSession.cs │ └── Example │ └── Example1.meta ├── README.md └── .gitignore /u3d/ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 5.6.4p4 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Unity3DSocket 2 | ============= 3 | 4 | Unity3D Socket (TCP) 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | u3d/Library 3 | u3d/Temp 4 | u3d/*.sln 5 | u3d/*.csproj 6 | u3d/*.userprefs -------------------------------------------------------------------------------- /u3d/ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luzexi/Unity3DSocket/HEAD/u3d/ProjectSettings/TagManager.asset -------------------------------------------------------------------------------- /u3d/ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luzexi/Unity3DSocket/HEAD/u3d/ProjectSettings/AudioManager.asset -------------------------------------------------------------------------------- /u3d/ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luzexi/Unity3DSocket/HEAD/u3d/ProjectSettings/InputManager.asset -------------------------------------------------------------------------------- /u3d/ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luzexi/Unity3DSocket/HEAD/u3d/ProjectSettings/NavMeshAreas.asset -------------------------------------------------------------------------------- /u3d/ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luzexi/Unity3DSocket/HEAD/u3d/ProjectSettings/TimeManager.asset -------------------------------------------------------------------------------- /u3d/ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luzexi/Unity3DSocket/HEAD/u3d/ProjectSettings/DynamicsManager.asset -------------------------------------------------------------------------------- /u3d/ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luzexi/Unity3DSocket/HEAD/u3d/ProjectSettings/EditorSettings.asset -------------------------------------------------------------------------------- /u3d/ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luzexi/Unity3DSocket/HEAD/u3d/ProjectSettings/NetworkManager.asset -------------------------------------------------------------------------------- /u3d/ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luzexi/Unity3DSocket/HEAD/u3d/ProjectSettings/ProjectSettings.asset -------------------------------------------------------------------------------- /u3d/ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luzexi/Unity3DSocket/HEAD/u3d/ProjectSettings/QualitySettings.asset -------------------------------------------------------------------------------- /u3d/ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luzexi/Unity3DSocket/HEAD/u3d/ProjectSettings/GraphicsSettings.asset -------------------------------------------------------------------------------- /u3d/ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luzexi/Unity3DSocket/HEAD/u3d/ProjectSettings/Physics2DSettings.asset -------------------------------------------------------------------------------- /u3d/ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luzexi/Unity3DSocket/HEAD/u3d/ProjectSettings/ClusterInputManager.asset -------------------------------------------------------------------------------- /u3d/ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luzexi/Unity3DSocket/HEAD/u3d/ProjectSettings/EditorBuildSettings.asset -------------------------------------------------------------------------------- /u3d/ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luzexi/Unity3DSocket/HEAD/u3d/ProjectSettings/UnityConnectSettings.asset -------------------------------------------------------------------------------- /u3d/Assets/Example.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d91029982598e7b4cabc4dd58db077a8 3 | folderAsset: yes 4 | timeCreated: 1523153149 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /u3d/Assets/Source.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3820a0fe6566b37469ae04cceb4301c5 3 | folderAsset: yes 4 | timeCreated: 1523153143 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /u3d/Assets/Source/Socket.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1a55457fba2a3ba4c8fb92c1c3c7a8be 3 | folderAsset: yes 4 | timeCreated: 1523153197 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /u3d/Assets/Example/Example1.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 172c65849c4544047b03948e1e9a719b 3 | folderAsset: yes 4 | timeCreated: 1523153165 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /u3d/Assets/Source/Socket/Common.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 02a5ddd869e397240939dd871746cb32 3 | folderAsset: yes 4 | timeCreated: 1523153197 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /u3d/Assets/Source/StreamBuffer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f4733e1f6fdb18f4d8becc0fb0632927 3 | timeCreated: 1523153198 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /u3d/Assets/Source/SwitchQueue.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1b9dc68530ac2fd478fbbfae0570fd80 3 | timeCreated: 1523161792 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /u3d/Assets/Source/TCPSession.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7912f818e6eba69478d6bbde063f0031 3 | timeCreated: 1523161792 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /u3d/Assets/Source/Socket/Common/NetQueue.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b0826784ce2bb494c86a6dc5f14d22a5 3 | timeCreated: 1523153197 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /u3d/Assets/Source/Socket/Common/PackBase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b0baf43545a631047a2e02eb9888fe7b 3 | timeCreated: 1523153197 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /u3d/Assets/Source/Socket/Common/NetEncrypt.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 776e6e8051dc17a4481851ca2ca2a057 3 | timeCreated: 1523153197 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /u3d/Assets/Source/SwitchQueue.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | 4 | namespace Game.Network 5 | { 6 | public class SwitchQueue where T : class { 7 | 8 | private Queue mConsumeQueue; 9 | private Queue mProduceQueue; 10 | 11 | public SwitchQueue() { 12 | mConsumeQueue = new Queue(16); 13 | mProduceQueue = new Queue(16); 14 | } 15 | 16 | public SwitchQueue(int capcity) { 17 | mConsumeQueue = new Queue(capcity); 18 | mProduceQueue = new Queue(capcity); 19 | } 20 | 21 | // producer 22 | public void Push( T obj ) { 23 | lock (mProduceQueue) 24 | { 25 | mProduceQueue.Enqueue( obj ); 26 | } 27 | } 28 | 29 | // consumer. 30 | public T Pop() { 31 | 32 | return (T)mConsumeQueue.Dequeue(); 33 | } 34 | 35 | public bool Empty() { 36 | return 0 == mConsumeQueue.Count; 37 | } 38 | 39 | public void Switch() { 40 | lock (mProduceQueue) 41 | { 42 | Swap( ref mConsumeQueue, ref mProduceQueue ); 43 | } 44 | } 45 | 46 | public void Clear() { 47 | lock (mProduceQueue) 48 | { 49 | mConsumeQueue.Clear(); 50 | mProduceQueue.Clear(); 51 | } 52 | } 53 | 54 | static void Swap< QT >( ref QT t1, ref QT t2 ) { 55 | 56 | QT temp = t1; 57 | t1 = t2; 58 | t2 = temp; 59 | } 60 | } 61 | 62 | } -------------------------------------------------------------------------------- /u3d/Assets/Source/Socket/Common/PackBase.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using System; 4 | using System.IO; 5 | 6 | 7 | // PackBase.cs 8 | // Lu Zexi 9 | // 2012-8-23 10 | 11 | 12 | namespace Game.Network 13 | { 14 | /// 15 | /// 基础包 16 | /// 17 | public class PacketBase 18 | { 19 | protected ushort m_usPacketId; //包ID 20 | public ushort m_usPacketSize; //包大小 21 | 22 | //private long m_lPublicKey; //公钥 23 | //private long m_lPrivateKey; //密钥 24 | 25 | public PacketBase() 26 | { 27 | this.m_usPacketId = 0; 28 | this.m_usPacketSize = 0; 29 | } 30 | 31 | /// 32 | /// 获取包ID 33 | /// 34 | /// 35 | public ushort GetPacketID() 36 | { 37 | return this.m_usPacketId; 38 | } 39 | 40 | /// 41 | /// 获取包大小 42 | /// 43 | /// 44 | public virtual ushort GetSize() 45 | { 46 | return (sizeof(ushort) + sizeof(ushort)); 47 | } 48 | 49 | /// 50 | /// 获取数据比特流 51 | /// 52 | /// 53 | public virtual void Write(StreamBuffer stream) 54 | { 55 | stream.WriteData(this.m_usPacketSize); 56 | stream.WriteData(this.m_usPacketId); 57 | } 58 | 59 | /// 60 | /// 设置由比特流而得到的数据 61 | /// 62 | /// 63 | public virtual void Load(StreamBuffer stream) 64 | { 65 | this.m_usPacketId = stream.ReadUInt16(); 66 | this.m_usPacketSize = stream.ReadUInt16(); 67 | } 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /u3d/Assets/Source/Socket/Common/NetEncrypt.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | // EnDecoding.cs 7 | // Lu Zexi 8 | // 2012-8-23 9 | 10 | 11 | 12 | namespace Game.Network 13 | { 14 | /// 15 | /// 加解密 16 | /// 17 | internal class CEncrypt 18 | { 19 | public readonly static int[] GAMESERVER_TO_CLIENT_KEY = { -73, -2, -50, -15, -58, -9, -74, -53, -74, -44, -65, -51, -69, -89, -74, -53, -75, -60, -73, -30, -80, -4, -61, -36, -44, -65 }; 20 | public readonly static int[] CLIENT_TO_GAMESERVER_KEY = { -73, -2, -50, -15, -58, -9, -74, -53, -74, -44, -65, -51, -69, -89, -74, -53, -75, -60, -73, -30, -80, -4, -61, -36, -44, -65 }; 21 | 22 | /// 23 | /// 加密 24 | /// 25 | /// 要加密的数据流 26 | /// 数据流偏移 27 | /// 加密的KEY 28 | /// KEY的偏移 29 | /// 总长度 30 | public static void Encoding(ref byte[] buff, int offset, int[] Key, int keyoffset, int len) 31 | { 32 | try 33 | { 34 | int keylen = Key.Length; 35 | for (int i = 0; i < len; ++i) 36 | { 37 | buff[i + offset] ^= (byte)(Key[(i + keyoffset) % keylen]); 38 | } 39 | } 40 | catch (Exception e) 41 | { 42 | // Error 43 | } 44 | 45 | 46 | } 47 | 48 | /// 49 | /// 加密 50 | /// 51 | /// 52 | public static byte[] EncryptBytes(byte[] buff) 53 | { 54 | Encoding( ref buff, 0, GAMESERVER_TO_CLIENT_KEY, 0, buff.Length); 55 | return buff; 56 | } 57 | 58 | /// 59 | /// 解密 60 | /// 61 | /// 要解密的数据流 62 | /// 数据流偏移 63 | /// 加密KEY 64 | /// KEY的偏移 65 | /// 总长度 66 | public static void Decoding(ref byte[] buff, int offset, int[] Key, int keyoffset, int len) 67 | { 68 | try 69 | { 70 | int keylen = Key.Length; 71 | for (int i = 0; i < len; ++i) 72 | { 73 | buff[i + offset] ^= (byte)(Key[(i + keyoffset) % keylen]); 74 | } 75 | } 76 | catch (Exception e) 77 | { 78 | // Error 79 | } 80 | } 81 | 82 | /// 83 | /// 解密 84 | /// 85 | /// 86 | public static byte[] DecryptBytes( byte[] buff ) 87 | { 88 | Decoding( ref buff, 0, CLIENT_TO_GAMESERVER_KEY, 0, buff.Length); 89 | return buff; 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /u3d/Assets/Source/Socket/Common/NetQueue.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | // NetQueue.cs 7 | // Lu Zexi 8 | // 2012-8-23 9 | 10 | 11 | namespace Game.Network 12 | { 13 | 14 | /// 15 | /// 网络队列类 16 | /// 17 | public sealed class NetQueue 18 | { 19 | private readonly object m_cLock; //关键锁 20 | private T[] m_lstItems; //队列 21 | private int m_iSize; //大小 22 | private int m_iHead; //队列头 23 | private int m_iCount; //数量 24 | 25 | public int Size 26 | { 27 | get { return this.m_iSize; } 28 | } 29 | public int Capacity 30 | { 31 | get { return this.m_lstItems.Length; } 32 | } 33 | 34 | public NetQueue(int capacity) 35 | { 36 | this.m_cLock = new object(); 37 | this.m_lstItems = new T[capacity]; 38 | } 39 | 40 | /// 41 | /// 设置新容量 42 | /// 43 | /// 44 | private void SetCapacity(int newSize) 45 | { 46 | if (this.m_iSize == 0) 47 | { 48 | this.m_lstItems = new T[newSize]; 49 | this.m_iHead = 0; 50 | return; 51 | } 52 | 53 | T[] newlst = new T[newSize]; 54 | 55 | if (this.m_iHead + this.m_iSize - 1 < this.m_lstItems.Length) 56 | { 57 | Array.Copy(this.m_lstItems, this.m_iHead, newlst, 0, this.m_iSize); 58 | } 59 | else 60 | { 61 | Array.Copy(this.m_lstItems, this.m_iHead, newlst, 0, this.m_lstItems.Length - this.m_iHead); 62 | Array.Copy(this.m_lstItems, 0, newlst, this.m_lstItems.Length - this.m_iHead, (this.m_iSize - (this.m_lstItems.Length - this.m_iHead))); 63 | } 64 | 65 | this.m_lstItems = newlst; 66 | this.m_iHead = 0; 67 | } 68 | 69 | /// 70 | /// 清除队列 71 | /// 72 | public void Clear() 73 | { 74 | lock (this.m_cLock) 75 | { 76 | for (int i = 0; i < this.m_lstItems.Length; i++) 77 | this.m_lstItems[i] = default(T); 78 | this.m_iHead = 0; 79 | this.m_iSize = 0; 80 | } 81 | } 82 | 83 | /// 84 | /// 推入队列 85 | /// 86 | /// 87 | public void Enqueue(T item) 88 | { 89 | lock (this.m_cLock) 90 | { 91 | if (this.m_iSize == this.m_lstItems.Length) 92 | SetCapacity(this.m_lstItems.Length + 8); 93 | 94 | int index = (this.m_iHead + this.m_iSize) % this.m_lstItems.Length; 95 | this.m_lstItems[index] = item; 96 | this.m_iSize++; 97 | } 98 | } 99 | 100 | /// 101 | /// 推入所有元素 102 | /// 103 | /// 104 | public void Enqueue(IEnumerable items) 105 | { 106 | lock (this.m_cLock) 107 | { 108 | foreach (var item in items) 109 | { 110 | if (this.m_iSize == this.m_lstItems.Length) 111 | { 112 | SetCapacity(this.m_lstItems.Length + 8); 113 | int index = (this.m_iHead + this.m_iSize) % this.m_lstItems.Length; 114 | this.m_lstItems[index] = item; 115 | this.m_iSize++; 116 | } 117 | } 118 | } 119 | } 120 | 121 | /// 122 | /// 推入元素到头队列 123 | /// 124 | /// 125 | public void EnqueueFront(T item) 126 | { 127 | lock (this.m_cLock) 128 | { 129 | if (this.m_iSize >= this.m_lstItems.Length) 130 | SetCapacity(this.m_lstItems.Length + 8); 131 | 132 | this.m_iHead--; 133 | if (this.m_iHead < 0) 134 | this.m_iHead = this.m_lstItems.Length - 1; 135 | this.m_lstItems[this.m_iHead] = item; 136 | this.m_iSize++; 137 | } 138 | } 139 | 140 | /// 141 | /// 推出元素 142 | /// 143 | /// 144 | /// 145 | public bool Dequeue(out T item) 146 | { 147 | if (this.m_iSize == 0) 148 | { 149 | item = default(T); 150 | return false; 151 | } 152 | 153 | lock (this.m_cLock) 154 | { 155 | item = this.m_lstItems[this.m_iHead]; 156 | this.m_lstItems[this.m_iHead] = default(T); 157 | this.m_iHead = (this.m_iHead + 1) % this.m_lstItems.Length; 158 | this.m_iSize--; 159 | return true; 160 | } 161 | } 162 | 163 | /// 164 | /// 将所有元素推出 165 | /// 166 | /// 167 | /// 168 | public int DequeueAll(IList addTo) 169 | { 170 | if (this.m_iSize == 0) 171 | return 0; 172 | 173 | lock (this.m_cLock) 174 | { 175 | int added = this.m_iSize; 176 | while (this.m_iSize > 0) 177 | { 178 | var item = this.m_lstItems[this.m_iHead]; 179 | addTo.Add(item); 180 | this.m_lstItems[this.m_iHead] = default(T); 181 | this.m_iHead = (this.m_iHead + 1) % this.m_lstItems.Length; 182 | this.m_iSize--; 183 | } 184 | return added; 185 | } 186 | } 187 | 188 | /// 189 | /// 获取指定偏移量的元素 190 | /// 191 | /// 192 | /// 193 | public T Peek(int offset) 194 | { 195 | if (this.m_iSize == 0) 196 | return default(T); 197 | 198 | lock (this.m_cLock) 199 | { 200 | return this.m_lstItems[(this.m_iHead + offset) % this.m_lstItems.Length]; 201 | } 202 | } 203 | 204 | /// 205 | /// 是否存在指定元素 206 | /// 207 | /// 208 | /// 209 | public bool Contain(T item) 210 | { 211 | lock (this.m_cLock) 212 | { 213 | int ptr = this.m_iHead; 214 | for (int i = 0; i < this.m_iSize; i++) 215 | { 216 | if (this.m_lstItems[ptr] == null) 217 | { 218 | if (item == null) 219 | return true; 220 | } 221 | else 222 | { 223 | if (this.m_lstItems[ptr].Equals(item)) 224 | return true; 225 | } 226 | ptr = (ptr + 1) % this.m_lstItems.Length; 227 | } 228 | return false; 229 | } 230 | } 231 | 232 | /// 233 | /// 获取所有元素 234 | /// 235 | /// 236 | public T[] ToArray() 237 | { 238 | lock (this.m_cLock) 239 | { 240 | T[] res = new T[this.m_iSize]; 241 | int ptr = this.m_iHead; 242 | for (int i = 0; i < this.m_iSize; i++) 243 | { 244 | res[i] = this.m_lstItems[ptr++]; 245 | if (ptr >= this.m_lstItems.Length) 246 | ptr = 0; 247 | } 248 | return res; 249 | } 250 | } 251 | 252 | } 253 | 254 | 255 | } 256 | 257 | -------------------------------------------------------------------------------- /u3d/Assets/Source/StreamBuffer.cs: -------------------------------------------------------------------------------- 1 | 2 | using System; 3 | using System.IO; 4 | using System.Runtime.InteropServices; 5 | using UnityEngine; 6 | 7 | // StreamBuffer.cs 8 | // Lu Zexi 9 | // 2012-8-23 10 | 11 | 12 | namespace Game.Network 13 | { 14 | public class StreamBuffer 15 | { 16 | private const int DEFAULT_BUFFER_SIZE = 256; 17 | private const int ADDITION_SIZE = 256; 18 | 19 | public byte[] m_lstBuffer; //buffer 20 | private int m_iRead; //read index 21 | public int ReadIndex 22 | { 23 | get{ return m_iRead; } 24 | } 25 | private int m_iWrite; //write index 26 | public int WriteIndex 27 | { 28 | get{ return m_iWrite;} 29 | } 30 | private int m_iSize; //buff size 31 | 32 | public StreamBuffer() 33 | { 34 | this.m_lstBuffer = new byte[DEFAULT_BUFFER_SIZE]; 35 | this.m_iSize = 0; 36 | this.m_iRead = this.m_iWrite = 0; 37 | } 38 | 39 | public StreamBuffer(byte[] buffer) 40 | { 41 | this.m_lstBuffer = buffer; 42 | this.m_iSize = buffer.Length; 43 | this.m_iRead = this.m_iWrite = 0; 44 | } 45 | 46 | //clear buffer 47 | public void Clear() 48 | { 49 | this.m_lstBuffer = new byte[16]; 50 | this.m_iSize = 0; 51 | this.m_iRead = 0; 52 | this.m_iWrite = 0; 53 | } 54 | 55 | //get size 56 | public int GetSize() 57 | { 58 | return this.m_iSize; 59 | } 60 | 61 | //write data 62 | public void Write(byte[] buffer, int size) 63 | { 64 | if (this.m_iWrite + size >= this.m_lstBuffer.Length) 65 | { 66 | FormationBuffer(); 67 | } 68 | if (this.m_iWrite + size >= this.m_lstBuffer.Length) 69 | { 70 | int size_num = size/ADDITION_SIZE + 1; 71 | AdditionSize(size_num); 72 | } 73 | //Array.Reverse(buffer);//大小端转换 74 | Array.Copy(buffer, 0, this.m_lstBuffer, this.m_iWrite, size); 75 | Write(size); 76 | } 77 | 78 | public void Write(byte[] buffer) 79 | { 80 | Write(buffer, buffer.Length); 81 | } 82 | 83 | //write index 84 | private void Write(int size) 85 | { 86 | this.m_iWrite += size; 87 | this.m_iSize += size; 88 | } 89 | 90 | #region Write data override 91 | 92 | //write data 93 | public void WriteData(int data) 94 | { 95 | byte[] res = BitConverter.GetBytes(data); 96 | Write(res, res.Length); 97 | } 98 | 99 | public void WriteData(uint data) 100 | { 101 | byte[] res = BitConverter.GetBytes(data); 102 | Write(res, res.Length); 103 | } 104 | 105 | public void WriteData(float data) 106 | { 107 | byte[] res = BitConverter.GetBytes(data); 108 | Write(res, res.Length); 109 | } 110 | 111 | public void WriteData(short data) 112 | { 113 | byte[] res = BitConverter.GetBytes(data); 114 | Write(res, res.Length); 115 | } 116 | 117 | public void WriteData(ushort data) 118 | { 119 | byte[] res = BitConverter.GetBytes(data); 120 | Write(res, res.Length); 121 | } 122 | 123 | public void WriteData(long data) 124 | { 125 | byte[] res = BitConverter.GetBytes(data); 126 | Write(res, res.Length); 127 | } 128 | 129 | public void WriteData(ulong data) 130 | { 131 | byte[] res = BitConverter.GetBytes(data); 132 | Write(res, res.Length); 133 | } 134 | 135 | public void WriteData(byte data) 136 | { 137 | byte[] res = new byte[1]; 138 | res[0] = data; 139 | Write(res, res.Length); 140 | } 141 | 142 | public void WriteData(double data) 143 | { 144 | byte[] res = BitConverter.GetBytes(data); 145 | Write(res, res.Length); 146 | } 147 | 148 | public void WriteData(bool data) 149 | { 150 | byte[] res = BitConverter.GetBytes(data); 151 | Write(res, res.Length); 152 | } 153 | 154 | public void WriteData(string data) 155 | { 156 | foreach (char item in data.ToCharArray()) 157 | { 158 | byte[] res = BitConverter.GetBytes(item); 159 | Write(res, res.Length); 160 | } 161 | } 162 | 163 | public void WriteData(char data) 164 | { 165 | byte[] res = BitConverter.GetBytes(data); 166 | Write(res, res.Length); 167 | } 168 | 169 | public void WriteData(char[] data) 170 | { 171 | foreach (char item in data) 172 | { 173 | byte[] res = BitConverter.GetBytes(item); 174 | Write(res, res.Length); 175 | } 176 | } 177 | 178 | #endregion 179 | 180 | #region Read 181 | 182 | //read data 183 | public byte[] Read(int size) 184 | { 185 | if (this.m_iRead + size > this.m_iWrite) 186 | { 187 | Debug.LogError("Buffer is smaller than read, must be something error."); 188 | return null; 189 | } 190 | 191 | byte[] tmpBuffer = new byte[size]; 192 | 193 | Array.Copy(this.m_lstBuffer, this.m_iRead, tmpBuffer, 0, size); 194 | this.m_iRead += size; 195 | this.m_iSize -= size; 196 | 197 | return tmpBuffer; 198 | } 199 | 200 | public int ReadInt32() 201 | { 202 | byte[] res = Read(sizeof(int)); 203 | return BitConverter.ToInt32(res, 0); 204 | } 205 | 206 | public uint ReadUInt32() 207 | { 208 | byte[] res = Read(sizeof(uint)); 209 | return BitConverter.ToUInt32(res, 0); 210 | } 211 | 212 | public short ReadInt16() 213 | { 214 | byte[] res = Read(sizeof(short)); 215 | return BitConverter.ToInt16(res, 0); 216 | } 217 | 218 | public ushort ReadUInt16() 219 | { 220 | byte[] res = Read(sizeof(ushort)); 221 | return BitConverter.ToUInt16(res, 0); 222 | } 223 | 224 | public long ReadInt64() 225 | { 226 | byte[] res = Read(sizeof(long)); 227 | return BitConverter.ToInt64(res, 0); 228 | } 229 | 230 | public ulong ReadUInt64() 231 | { 232 | byte[] res = Read(sizeof(long)); 233 | return BitConverter.ToUInt64(res, 0); 234 | } 235 | 236 | public bool ReadBool() 237 | { 238 | byte[] res = Read(sizeof(bool)); 239 | return BitConverter.ToBoolean(res, 0); 240 | } 241 | 242 | public float ReadFloat() 243 | { 244 | byte[] res = Read(sizeof(float)); 245 | return BitConverter.ToSingle(res, 0); 246 | } 247 | 248 | public double ReadDouble() 249 | { 250 | byte[] res = Read(sizeof(double)); 251 | return BitConverter.ToDouble(res, 0); 252 | } 253 | 254 | public byte ReadByte() 255 | { 256 | byte[] res = Read(sizeof(byte)); 257 | return res[0]; 258 | } 259 | 260 | public char ReadChar() 261 | { 262 | byte[] res = Read(sizeof(char)); 263 | return BitConverter.ToChar(res, 0); 264 | } 265 | 266 | public char[] ReadChars(int num) 267 | { 268 | char[] data = new char[num]; 269 | for (int i = 0; i < num; i++) 270 | { 271 | byte[] res = Read(sizeof(char)); 272 | data[i] = BitConverter.ToChar(res, 0); 273 | } 274 | return data; 275 | } 276 | 277 | public string ReadStr(int num) 278 | { 279 | string data = ""; 280 | for (int i = 0; i < num; i++) 281 | { 282 | byte[] res = Read(sizeof(char)); 283 | data += BitConverter.ToChar(res, 0); 284 | } 285 | return data; 286 | } 287 | 288 | #endregion 289 | 290 | 291 | //addition size 292 | private void AdditionSize(int num = 1) 293 | { 294 | byte[] array = new byte[m_lstBuffer.Length + ADDITION_SIZE * num]; 295 | Array.Copy(this.m_lstBuffer, this.m_iRead, array, 0, this.m_iSize); 296 | m_lstBuffer = array; 297 | this.m_iRead = 0; 298 | this.m_iWrite = this.m_iRead + this.m_iSize; 299 | } 300 | 301 | //format buff 302 | private void FormationBuffer() 303 | { 304 | int index = 0; 305 | for(int i = 0 ; i> 0); 54 | p[1 + offset] = (byte)(w >> 8); 55 | return 2; 56 | } 57 | 58 | /* decode 16 bits unsigned int (lsb) */ 59 | public static int tcpsession_decode16u(byte[] p, int offset, ref UInt16 c) 60 | { 61 | if(p == null || p.Length < 2 || p.Length - offset < 2) return 0; 62 | UInt16 result = 0; 63 | result |= (UInt16)p[0 + offset]; 64 | result |= (UInt16)(p[1 + offset] << 8); 65 | c = result; 66 | return 2; 67 | } 68 | 69 | /* encode 32 bits unsigned int (lsb) */ 70 | public static int tcpsession_encode32u(byte[] p, int offset, UInt32 l) 71 | { 72 | if(p == null || p.Length < 4 || p.Length - offset < 4) return 0; 73 | p[0 + offset] = (byte)(l >> 0); 74 | p[1 + offset] = (byte)(l >> 8); 75 | p[2 + offset] = (byte)(l >> 16); 76 | p[3 + offset] = (byte)(l >> 24); 77 | return 4; 78 | } 79 | 80 | /* decode 32 bits unsigned int (lsb) */ 81 | public static int tcpsession_decode32u(byte[] p, int offset, ref UInt32 c) 82 | { 83 | if(p == null || p.Length < 4 || p.Length - offset < 4) return 0; 84 | UInt32 result = 0; 85 | result |= (UInt32)p[0 + offset]; 86 | result |= (UInt32)(p[1 + offset] << 8); 87 | result |= (UInt32)(p[2 + offset] << 16); 88 | result |= (UInt32)(p[3 + offset] << 24); 89 | c = result; 90 | return 4; 91 | } 92 | 93 | private const int RECEIVE_MAX_NUM = 1024; 94 | private const int SEND_MAX_SIZE = 14000; 95 | private const float SEND_INTERVAL_TIME = 0.2f; 96 | private const int HEAD_SIZE = 6; 97 | 98 | private Socket m_cSocket; 99 | 100 | private byte[] mReceiveArray; 101 | private StreamBuffer m_cReceiveBuffer; //receive buffer 102 | private StreamBuffer m_cSendBuffer; //send buffer 103 | private Queue mQueSend; //send queue 104 | private SwitchQueue m_cReceiveQueue; //receive queue 105 | 106 | private string m_strAddress; //address of server 107 | private int m_iPort; //port 108 | 109 | private float mSendStartTime; 110 | 111 | private SESSION_STATUS m_cStatus; //status 112 | 113 | private System.Action mCallback; 114 | 115 | public TCPSession(System.Action _callback) 116 | { 117 | mReceiveArray = new byte[RECEIVE_MAX_NUM]; 118 | 119 | m_cStatus = SESSION_STATUS.NO_CONNECT; 120 | 121 | m_cReceiveBuffer = new StreamBuffer(); 122 | m_cSendBuffer = new StreamBuffer(); 123 | 124 | mQueSend = new Queue(); 125 | m_cReceiveQueue = new SwitchQueue(128); 126 | 127 | mCallback = _callback; 128 | } 129 | 130 | public SESSION_STATUS GetStatus() 131 | { 132 | return m_cStatus; 133 | } 134 | 135 | private void ChangeStatus(SESSION_STATUS status) 136 | { 137 | m_cStatus = status; 138 | if(status == SESSION_STATUS.CONNECT_SUCCESS) 139 | { 140 | if(mCallback != null) 141 | { 142 | mCallback(EVENT.CONNECTED, null , null); 143 | } 144 | } 145 | 146 | if(status == SESSION_STATUS.CONNECT_FAILED_CONNECT_ERROR) 147 | { 148 | if(mCallback != null) 149 | { 150 | mCallback(EVENT.CONNECT_FAILED, null , "connect error"); 151 | } 152 | } 153 | 154 | if(status == SESSION_STATUS.CONNECT_FAILED_TIME_OUT) 155 | { 156 | if(mCallback != null) 157 | { 158 | mCallback(EVENT.CONNECT_FAILED, null , "connect time out"); 159 | } 160 | } 161 | 162 | if(status == SESSION_STATUS.CONNECT_EXIT) 163 | { 164 | if(mCallback != null) 165 | { 166 | mCallback(EVENT.CONNECT_DISCONNECT, null , "disconnect"); 167 | } 168 | } 169 | } 170 | 171 | public void Connect(string address, int port) 172 | { 173 | try 174 | { 175 | m_strAddress = address; 176 | m_iPort = port; 177 | 178 | IPHostEntry iphostInfo = Dns.GetHostEntry(address); 179 | IPAddress ipAddress = iphostInfo.AddressList[0]; 180 | IPEndPoint remoteEP = new IPEndPoint(ipAddress, port); 181 | 182 | m_cSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 183 | if (m_cSocket == null) 184 | { 185 | //ERROR 186 | throw new Exception("Socket create error."); 187 | } 188 | m_cSocket.NoDelay = true; 189 | m_cSocket.BeginConnect(remoteEP, new AsyncCallback(ConnectCallBack), m_cSocket); 190 | } 191 | catch (Exception e) 192 | { 193 | Debug.LogError(e.StackTrace); 194 | ChangeStatus(SESSION_STATUS.CONNECT_FAILED_CONNECT_ERROR); 195 | } 196 | } 197 | 198 | private void ConnectCallBack(IAsyncResult ar) 199 | { 200 | try 201 | { 202 | m_cSocket = (Socket)ar.AsyncState; 203 | if (m_cSocket == null) 204 | { 205 | //ERROR 206 | throw new Exception("Socket connect Failed."); 207 | } 208 | m_cSocket.EndConnect(ar); 209 | ChangeStatus(SESSION_STATUS.CONNECT_SUCCESS); 210 | Receive(); 211 | } 212 | catch (Exception e) 213 | { 214 | Debug.LogError(e.StackTrace); 215 | ChangeStatus(SESSION_STATUS.CONNECT_FAILED_CONNECT_ERROR); 216 | 217 | } 218 | } 219 | 220 | public void DisConnect() 221 | { 222 | try 223 | { 224 | if (m_cSocket != null) 225 | { 226 | m_cSocket.Shutdown(SocketShutdown.Both); 227 | m_cSocket.Close(); 228 | } 229 | m_cSocket = null; 230 | ChangeStatus(SESSION_STATUS.CONNECT_EXIT); 231 | } 232 | catch (Exception e) 233 | { 234 | Debug.LogError(e.StackTrace); 235 | ChangeStatus(SESSION_STATUS.CONNECT_FAILED_CONNECT_ERROR); 236 | } 237 | } 238 | 239 | private bool Receive() 240 | { 241 | try 242 | { 243 | if(m_cStatus != SESSION_STATUS.CONNECT_SUCCESS) return false; 244 | 245 | if (m_cSocket == null) 246 | { 247 | throw new Exception("Error , the socket is null."); 248 | } 249 | m_cSocket.BeginReceive(mReceiveArray, 0, 250 | RECEIVE_MAX_NUM, 251 | SocketFlags.None, new AsyncCallback(ReceiveCallBack), mReceiveArray); 252 | return true; 253 | } 254 | catch (Exception e) 255 | { 256 | Debug.LogError(e.StackTrace); 257 | ChangeStatus(SESSION_STATUS.CONNECT_FAILED_CONNECT_ERROR); 258 | } 259 | return false; 260 | } 261 | 262 | private void ReceiveCallBack(IAsyncResult ar) 263 | { 264 | try 265 | { 266 | int bytesCount = m_cSocket.EndReceive(ar); 267 | if (bytesCount > 0) 268 | { 269 | byte[] data = new byte[bytesCount]; 270 | Array.Copy(mReceiveArray, 0 , data, 0 , bytesCount); 271 | m_cReceiveQueue.Push(data); 272 | 273 | Receive(); 274 | } 275 | else 276 | { 277 | throw new Exception("Receive bytes error."); 278 | } 279 | } 280 | catch (Exception e) 281 | { 282 | Debug.LogError(e.StackTrace); 283 | ChangeStatus(SESSION_STATUS.CONNECT_FAILED_CONNECT_ERROR); 284 | } 285 | } 286 | 287 | public void Update() 288 | { 289 | ProcessReceive(); 290 | ProcessSend(); 291 | } 292 | 293 | public void Send(byte[] send_buffer) 294 | { 295 | mQueSend.Enqueue(send_buffer); 296 | } 297 | 298 | private void ProcessSend() 299 | { 300 | try 301 | { 302 | if(m_cStatus != SESSION_STATUS.CONNECT_SUCCESS) return; 303 | if( Time.time - mSendStartTime < SEND_INTERVAL_TIME ) return; 304 | 305 | int _packsize = 0; 306 | m_cSendBuffer.Clear(); 307 | for( ; mQueSend.Count > 0 ; ) 308 | { 309 | byte[] que_buffer = mQueSend.Peek(); 310 | if((_packsize > 0 && que_buffer.Length + _packsize > SEND_MAX_SIZE) || que_buffer == null) 311 | { 312 | break; 313 | } 314 | _packsize += que_buffer.Length; 315 | m_cSendBuffer.Write(que_buffer, que_buffer.Length); 316 | mQueSend.Dequeue(); 317 | } 318 | if (m_cSendBuffer.GetSize() > 0) 319 | { 320 | if (m_cSocket == null) 321 | { 322 | throw new Exception("The socket is null."); 323 | } 324 | byte[] buffer = m_cSendBuffer.Read(m_cSendBuffer.GetSize()); 325 | if (buffer == null) 326 | { 327 | throw new Exception("The the send buffer is null."); 328 | } 329 | 330 | //加密 331 | //buffer = Packing.PackingEncode(buffer, pb.GetSize() ); 332 | 333 | mSendStartTime = Time.time; 334 | 335 | m_cSocket.BeginSend(buffer, 0, buffer.Length, 336 | SocketFlags.DontRoute, new AsyncCallback(SendCallBack), m_cSocket); 337 | } 338 | } 339 | catch (Exception e) 340 | { 341 | Debug.LogError(e.StackTrace); 342 | ChangeStatus(SESSION_STATUS.CONNECT_FAILED_CONNECT_ERROR); 343 | } 344 | } 345 | 346 | private void SendCallBack(IAsyncResult ar) 347 | { 348 | int bytesSend = m_cSocket.EndSend(ar); 349 | if (bytesSend <= 0) 350 | { 351 | Debug.LogError("send failed"); 352 | ChangeStatus(SESSION_STATUS.CONNECT_FAILED_CONNECT_ERROR); 353 | } 354 | } 355 | 356 | private void ProcessReceive() 357 | { 358 | m_cReceiveQueue.Switch(); 359 | 360 | while(!m_cReceiveQueue.Empty()) 361 | { 362 | m_cReceiveBuffer.Write(m_cReceiveQueue.Pop()); 363 | } 364 | 365 | for( ; m_cReceiveBuffer.GetSize() >= HEAD_SIZE ; ) 366 | { 367 | UInt16 pack_size = 0; 368 | int offset = 0; 369 | offset += tcpsession_decode16u(m_cReceiveBuffer.m_lstBuffer, offset, ref pack_size); 370 | if (m_cReceiveBuffer.GetSize() >= HEAD_SIZE + pack_size) 371 | { 372 | byte[] buffer = m_cReceiveBuffer.Read(HEAD_SIZE + pack_size); 373 | 374 | //decrypt 375 | //buffer = Packing.PackingDecode(buffer, head.m_usPacketSize); 376 | 377 | if (buffer != null) 378 | { 379 | if(mCallback != null) 380 | { 381 | mCallback(EVENT.DATA_RECEIVE, buffer, null); 382 | } 383 | } 384 | else 385 | { 386 | break; 387 | } 388 | } 389 | else 390 | { 391 | break; 392 | } 393 | } 394 | } 395 | 396 | } 397 | } 398 | 399 | --------------------------------------------------------------------------------