這篇文章主要介紹了socket傳輸protobuf字節(jié)流的示例分析,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
創(chuàng)新互聯(lián)一直通過網(wǎng)站建設(shè)和網(wǎng)站營(yíng)銷幫助企業(yè)獲得更多客戶資源。 以"深度挖掘,量身打造,注重實(shí)效"的一站式服務(wù),以成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)、外貿(mào)網(wǎng)站建設(shè)、移動(dòng)互聯(lián)產(chǎn)品、成都營(yíng)銷網(wǎng)站建設(shè)服務(wù)為核心業(yè)務(wù)。10年網(wǎng)站制作的經(jīng)驗(yàn),使用新網(wǎng)站建設(shè)技術(shù),全新開發(fā)出的標(biāo)準(zhǔn)網(wǎng)站,不但價(jià)格便宜而且實(shí)用、靈活,特別適合中小公司網(wǎng)站制作。網(wǎng)站管理系統(tǒng)簡(jiǎn)單易用,維護(hù)方便,您可以完全操作網(wǎng)站資料,是中小公司快速網(wǎng)站建設(shè)的選擇。
使用多線程收發(fā)消息
//創(chuàng)建消息數(shù)據(jù)模型 2 //正式項(xiàng)目中,消息的結(jié)構(gòu)一般是消息長(zhǎng)度+消息id+消息主體內(nèi)容 3 public class Message 4 { public IExtensible protobuf; public int messageId; 7 } 8 9 public class SocketClientTemp : MonoBehaviour 10 { 11 const int packageMaxLength = 1024; 12 13 Socket mSocket; 14 Thread threadSend; 15 Thread threadRecive; 16 Queue<Message> allMessages = new Queue<Message>(); 17 Queue<byte[]> sendQueue = new Queue<byte[]>(); public bool Init() 20 { 21 //創(chuàng)建一個(gè)socket對(duì)象 22 mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 23 return SocketConnection("此處是ip", 1111); 24 } 25 26 void Update() 27 { 28 AnalysisMessage(); 29 } 30 31 /// <summary> 32 /// 建立服務(wù)器連接 33 /// </summary> 34 /// <param name="ip">服務(wù)器的ip地址</param> 35 /// <param name="port">端口</param> 36 bool SocketConnection(string ip, int port) 37 { 38 try 39 { 40 IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(ip), port); 41 //同步連接服務(wù)器,實(shí)際使用時(shí)推薦使用異步連接,處理方式會(huì)在下一篇講斷線重連時(shí)講到 42 mSocket.Connect(ipep); 43 //連接成功后,創(chuàng)建兩個(gè)線程,分別用于發(fā)送和接收消息 44 threadSend = new Thread(new ThreadStart(SendMessage)); 45 threadSend.Start(); 46 threadRecive = new Thread(new ThreadStart(ReceiveMessage)); 47 threadRecive.Start(); 48 return true; 49 } 50 catch (Exception e) 51 { 52 Debug.Log(e.ToString()); 53 Close(); 54 return false; 55 } } #region ...發(fā)送消息 59 /// <summary> 60 /// 添加數(shù)據(jù)到發(fā)送隊(duì)列 61 /// </summary> 62 /// <param name="protobufModel"></param> 63 /// <param name="messageId"></param> 64 public void AddSendMessageQueue(IExtensible protobufModel, int messageId) 65 { 66 sendQueue.Enqueue(BuildPackage(protobufModel, messageId)); 67 } void SendMessage() 70 { 71 //循環(huán)獲取發(fā)送隊(duì)列中第一個(gè)數(shù)據(jù),然后發(fā)送到服務(wù)器 72 while (true) 73 { 74 if (sendQueue.Count == 0) 75 { 76 Thread.Sleep(100); 77 continue; 78 } 79 if (!mSocket.Connected) 80 { 81 Close(); 82 break; 83 } 84 else 85 Send(sendQueue.Peek()); //發(fā)送隊(duì)列中第一條數(shù)據(jù) 86 } 87 } 88 89 void Send(byte[] bytes) 90 { 91 try 92 { 93 mSocket.Send(bytes, SocketFlags.None); 94 //發(fā)送成功后,從發(fā)送隊(duì)列中移除已發(fā)送的消息 95 sendQueue.Dequeue(); 96 } 97 catch (SocketException e) 98 { 99 //如果錯(cuò)誤碼為10035,說明服務(wù)器緩存區(qū)滿了,所以等100毫秒再次發(fā)送100 if (e.NativeErrorCode == 10035)101 {102 Thread.Sleep(100);103 Send(bytes);104 }105 else106 Debug.Log(e.ToString());107 }108 }109 #endregion110 111 #region ...接收消息112 /// <summary>113 /// 解析收到的消息114 /// </summary>115 void AnalysisMessage()116 {117 while (allMessages.Count > 0)118 {119 int id = allMessages.Dequeue().messageId;120 switch (id)121 {122 //根據(jù)消息id做不同的處理123 }124 }125 }126 127 /// <summary>128 /// 接收數(shù)據(jù)129 /// </summary>130 void ReceiveMessage()131 {132 while (true)133 {134 if (!mSocket.Connected)135 break;136 byte[] recvBytesHead = GetBytesReceive(4);137 int bodyLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(recvBytesHead, 0));138 byte[] recvBytesBody = GetBytesReceive(bodyLength);139 140 byte[] messageId = new byte[4];141 Array.Copy(recvBytesBody, 0, messageId, 0, 4);142 byte[] messageBody = new byte[bodyLength - 4];143 Array.Copy(recvBytesBody, 4, messageBody, 0, bodyLength - 4);144 145 if (BitConverter.IsLittleEndian)146 Array.Reverse(messageId);147 FillAllPackages(BitConverter.ToInt32(messageId, 0), messageBody);148 } } /// <summary>152 /// 填充接收消息隊(duì)列153 /// </summary>154 /// <param name="messageId"></param>155 /// <param name="messageBody"></param>156 void FillAllPackages(int messageId, byte[] messageBody)157 {158 switch (messageId)159 {160 //根據(jù)消息id處理消息,并添加到接收消息隊(duì)列161 case 1:162 allMessages.Enqueue(new Message() 163 {164 protobuf = ProtobufSerilizer.DeSerialize<TestTemp>(messageBody), 165 messageId = messageId 166 });167 break;168 }169 }170 171 /// <summary>172 /// 接收數(shù)據(jù)并處理173 /// </summary>174 /// <param name="length"></param>175 /// <returns></returns>176 byte[] GetBytesReceive(int length)177 {178 byte[] recvBytes = new byte[length];179 while (length > 0)180 {181 byte[] receiveBytes = new byte[length < packageMaxLength ? length : packageMaxLength];182 int iBytesBody = 0;183 if (length >= receiveBytes.Length)184 iBytesBody = mSocket.Receive(receiveBytes, receiveBytes.Length, 0);185 else186 iBytesBody = mSocket.Receive(receiveBytes, length, 0);187 receiveBytes.CopyTo(recvBytes, recvBytes.Length - length);188 length -= iBytesBody;189 }190 return recvBytes;191 }192 #endregion193 194 /// <summary>195 /// 構(gòu)建消息數(shù)據(jù)包196 /// </summary>197 /// <param name="protobufModel"></param>198 /// <param name="messageId"></param>199 byte[] BuildPackage(IExtensible protobufModel, int messageId)200 {201 byte[] b;202 if (protobufModel != null)203 b = ProtobufSerilizer.Serialize(protobufModel);204 else205 b = new byte[0];206 //消息長(zhǎng)度(int數(shù)據(jù),長(zhǎng)度4) + 消息id(int數(shù)據(jù),長(zhǎng)度4) + 消息主體內(nèi)容207 ByteBuffer buf = ByteBuffer.Allocate(b.Length + 4 + 4);208 //消息長(zhǎng)度 = 消息主體內(nèi)容長(zhǎng)度 + 消息id長(zhǎng)度209 buf.WriteInt(b.Length + 4);210 buf.WriteInt(messageId);211 212 if (protobufModel != null)213 buf.WriteBytes(b);214 return buf.GetBytes();215 }216 217 void OnDestroy()218 {219 //停止運(yùn)行后,如果不關(guān)閉socket多線程,再次運(yùn)行時(shí),unity會(huì)卡死220 Close();221 }222 223 /// <summary>224 /// 關(guān)閉socket,終止線程225 /// </summary>226 public void Close()227 {228 if (mSocket != null)229 {230 //微軟官方推薦在關(guān)閉socket前先shutdown,但是經(jīng)過測(cè)試,發(fā)現(xiàn)網(wǎng)絡(luò)斷開后,shutdown會(huì)無(wú)法執(zhí)行231 if (mSocket.Connected)232 mSocket.Shutdown(SocketShutdown.Both);233 mSocket.Close();234 mSocket = null;235 }236 //關(guān)閉線程237 if (threadSend != null)238 threadSend.Abort();239 if (threadRecive != null)240 threadRecive.Abort();241 threadSend = null;242 threadRecive = null;243 }244 }
到這里,使用socket處理消息的收發(fā)就基本結(jié)束了。
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“socket傳輸protobuf字節(jié)流的示例分析”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來學(xué)習(xí)!
文章標(biāo)題:socket傳輸protobuf字節(jié)流的示例分析
網(wǎng)頁(yè)鏈接:http://jinyejixie.com/article26/jopjcg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站制作、網(wǎng)站導(dǎo)航、響應(yīng)式網(wǎng)站、外貿(mào)建站、虛擬主機(jī)、定制網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)