91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

socket如何傳輸protobuf字節流

發布時間:2021-09-17 09:25:02 來源:億速云 閱讀:146 作者:小新 欄目:編程語言

小編給大家分享一下socket如何傳輸protobuf字節流,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

首先的拼接數據包

 1     /// <summary> 2     /// 構建消息數據包 3     /// </summary> 4     /// <param name="protobufModel"></param> 5     byte[] BuildPackage(IExtensible protobufModel) 6     { 7         if (protobufModel != null) 8         { 9             byte[] b = ProtobufSerilizer.Serialize(protobufModel);10 11             ByteBuffer buf = ByteBuffer.Allocate(b.Length + 4);12             buf.WriteInt(b.Length);13             buf.WriteBytes(b);14             return buf.GetBytes();15         }16         return null;17     }

代碼中使用的ByteBuffer工具java中有提供,但是c#中是沒有的,源碼摘至,不過作者并未在工具中添加獲取所有字節碼的方法,所以自己添加了一個GetBytes()方法

  1 using System;  2 using System.Collections.Generic;  3   4 /// <summary>  5 /// 字節緩沖處理類,本類僅處理大字節序  6 /// 警告,本類非線程安全  7 /// </summary>  8 public class ByteBuffer  9 { 10     //字節緩存區 11     private byte[] buf; 12     //讀取索引 13     private int readIndex = 0; 14     //寫入索引 15     private int writeIndex = 0; 16     //讀取索引標記 17     private int markReadIndex = 0; 18     //寫入索引標記 19     private int markWirteIndex = 0; 20     //緩存區字節數組的長度 21     private int capacity; 22  23     //對象池 24     private static List<ByteBuffer> pool = new List<ByteBuffer>(); 25     private static int poolMaxCount = 200; 26     //此對象是否池化 27     private bool isPool = false; 28  29     /// <summary> 30     /// 構造方法 31     /// </summary> 32     /// <param name="capacity">初始容量</param> 33     private ByteBuffer(int capacity) 34     { 35         buf = new byte[capacity]; 36         this.capacity = capacity; 37     } 38  39     /// <summary> 40     /// 構造方法 41     /// </summary> 42     /// <param name="bytes">初始字節數組</param> 43     private ByteBuffer(byte[] bytes) 44     { 45         buf = bytes; 46         this.capacity = bytes.Length; 47         this.readIndex = 0; 48         this.writeIndex = bytes.Length + 1; 49     } 50  51     /// <summary> 52     /// 構建一個capacity長度的字節緩存區ByteBuffer對象 53     /// </summary> 54     /// <param name="capacity">初始容量</param> 55     /// <returns>ByteBuffer對象</returns> 56     public static ByteBuffer Allocate(int capacity) 57     { 58         return new ByteBuffer(capacity); 59     } 60  61     /// <summary> 62     /// 構建一個以bytes為字節緩存區的ByteBuffer對象,一般不推薦使用 63     /// </summary> 64     /// <param name="bytes">初始字節數組</param> 65     /// <returns>ByteBuffer對象</returns> 66     public static ByteBuffer Allocate(byte[] bytes) 67     { 68         return new ByteBuffer(bytes); 69     } 70  71     /// <summary> 72     /// 獲取一個池化的ByteBuffer對象,池化的對象必須在調用Dispose后才會推入池中,否則此方法等同于Allocate(int capacity)方法,此方法為線程安全的 73     /// </summary> 74     /// <param name="capacity">ByteBuffer對象的初始容量大小,如果緩存池中沒有對象,則對象的容量大小為此值,否則為池中對象的實際容量值</param> 75     /// <returns></returns> 76     public static ByteBuffer GetFromPool(int capacity) 77     { 78         lock (pool) 79         { 80             ByteBuffer bbuf; 81             if (pool.Count == 0) 82             { 83                 bbuf = Allocate(capacity); 84                 bbuf.isPool = true; 85                 return bbuf; 86             } 87             int lastIndex = pool.Count - 1; 88             bbuf = pool[lastIndex]; 89             pool.RemoveAt(lastIndex); 90             if (!bbuf.isPool) 91             { 92                 bbuf.isPool = true; 93             } 94             return bbuf; 95         } 96     } 97  98     /// <summary> 99     /// 根據length長度,確定大于此leng的最近的2次方數,如length=7,則返回值為8100     /// </summary>101     /// <param name="length">參考容量</param>102     /// <returns>比參考容量大的最接近的2次方數</returns>103     private int FixLength(int length)104     {105         int n = 2;106         int b = 2;107         while (b < length)108         {109             b = 2 << n;110             n++;111         }112         return b;113     }114 115     /// <summary>116     /// 翻轉字節數組,如果本地字節序列為低字節序列,則進行翻轉以轉換為高字節序列117     /// </summary>118     /// <param name="bytes">待轉為高字節序的字節數組</param>119     /// <returns>高字節序列的字節數組</returns>120     private byte[] flip(byte[] bytes)121     {122         if (BitConverter.IsLittleEndian)123         {124             Array.Reverse(bytes);125         }126         return bytes;127     }128 129     /// <summary>130     /// 確定內部字節緩存數組的大小131     /// </summary>132     /// <param name="currLen">當前容量</param>133     /// <param name="futureLen">將來的容量</param>134     /// <returns>將來的容量</returns>135     private int FixSizeAndReset(int currLen, int futureLen)136     {137         if (futureLen > currLen)138         {139             //以原大小的2次方數的兩倍確定內部字節緩存區大小140             int size = FixLength(currLen) * 2;141             if (futureLen > size)142             {143                 //以將來的大小的2次方的兩倍確定內部字節緩存區大小144                 size = FixLength(futureLen) * 2;145             }146             byte[] newbuf = new byte[size];147             Array.Copy(buf, 0, newbuf, 0, currLen);148             buf = newbuf;149             capacity = newbuf.Length;150         }151         return futureLen;152     }153 154     /// <summary>155     /// 將bytes字節數組從startIndex開始的length字節寫入到此緩存區156     /// </summary>157     /// <param name="bytes">待寫入的字節數據</param>158     /// <param name="startIndex">寫入的開始位置</param>159     /// <param name="length">寫入的長度</param>160     public void WriteBytes(byte[] bytes, int startIndex, int length)161     {162         int offset = length - startIndex;163         if (offset <= 0) return;164         int total = offset + writeIndex;165         int len = buf.Length;166         FixSizeAndReset(len, total);167         for (int i = writeIndex, j = startIndex; i < total; i++, j++)168         {169             buf[i] = bytes[j];170         }171         writeIndex = total;172     }173 174     /// <summary>175     /// 將字節數組中從0到length的元素寫入緩存區176     /// </summary>177     /// <param name="bytes">待寫入的字節數據</param>178     /// <param name="length">寫入的長度</param>179     public void WriteBytes(byte[] bytes, int length)180     {181         WriteBytes(bytes, 0, length);182     }183 184     /// <summary>185     /// 將字節數組全部寫入緩存區186     /// </summary>187     /// <param name="bytes">待寫入的字節數據</param>188     public void WriteBytes(byte[] bytes)189     {190         WriteBytes(bytes, bytes.Length);191     }192 193     /// <summary>194     /// 將一個ByteBuffer的有效字節區寫入此緩存區中195     /// </summary>196     /// <param name="buffer">待寫入的字節緩存區</param>197     public void Write(ByteBuffer buffer)198     {199         if (buffer == null) return;200         if (buffer.ReadableBytes() <= 0) return;201         WriteBytes(buffer.ToArray());202     }203 204     /// <summary>205     /// 寫入一個int16數據206     /// </summary>207     /// <param name="value">short數據</param>208     public void WriteShort(short value)209     {210         WriteBytes(flip(BitConverter.GetBytes(value)));211     }212 213     /// <summary>214     /// 寫入一個ushort數據215     /// </summary>216     /// <param name="value">ushort數據</param>217     public void WriteUshort(ushort value)218     {219         WriteBytes(flip(BitConverter.GetBytes(value)));220     }221 222     /// <summary>223     /// 寫入一個int32數據224     /// </summary>225     /// <param name="value">int數據</param>226     public void WriteInt(int value)227     {228         //byte[] array = new byte[4];229         //for (int i = 3; i >= 0; i--)230         //{231         //    array[i] = (byte)(value & 0xff);232         //    value = value >> 8;233         //}234         //Array.Reverse(array);235         //Write(array);236         WriteBytes(flip(BitConverter.GetBytes(value)));237     }238 239     /// <summary>240     /// 寫入一個uint32數據241     /// </summary>242     /// <param name="value">uint數據</param>243     public void WriteUint(uint value)244     {245         WriteBytes(flip(BitConverter.GetBytes(value)));246     }247 248     /// <summary>249     /// 寫入一個int64數據250     /// </summary>251     /// <param name="value">long數據</param>252     public void WriteLong(long value)253     {254         WriteBytes(flip(BitConverter.GetBytes(value)));255     }256 257     /// <summary>258     /// 寫入一個uint64數據259     /// </summary>260     /// <param name="value">ulong數據</param>261     public void WriteUlong(ulong value)262     {263         WriteBytes(flip(BitConverter.GetBytes(value)));264     }265 266     /// <summary>267     /// 寫入一個float數據268     /// </summary>269     /// <param name="value">float數據</param>270     public void WriteFloat(float value)271     {272         WriteBytes(flip(BitConverter.GetBytes(value)));273     }274 275     /// <summary>276     /// 寫入一個byte數據277     /// </summary>278     /// <param name="value">byte數據</param>279     public void WriteByte(byte value)280     {281         int afterLen = writeIndex + 1;282         int len = buf.Length;283         FixSizeAndReset(len, afterLen);284         buf[writeIndex] = value;285         writeIndex = afterLen;286     }287 288     /// <summary>289     /// 寫入一個byte數據290     /// </summary>291     /// <param name="value">byte數據</param>292     public void WriteByte(int value)293     {294         byte b = (byte)value;295         WriteByte(b);296     }297 298     /// <summary>299     /// 寫入一個double類型數據300     /// </summary>301     /// <param name="value">double數據</param>302     public void WriteDouble(double value)303     {304         WriteBytes(flip(BitConverter.GetBytes(value)));305     }306 307     /// <summary>308     /// 寫入一個字符309     /// </summary>310     /// <param name="value"></param>311     public void WriteChar(char value)312     {313         WriteBytes(flip(BitConverter.GetBytes(value)));314     }315 316     /// <summary>317     /// 寫入一個布爾型數據318     /// </summary>319     /// <param name="value"></param>320     public void WriteBoolean(bool value)321     {322         WriteBytes(flip(BitConverter.GetBytes(value)));323     }324 325     /// <summary>326     /// 讀取一個字節327     /// </summary>328     /// <returns>字節數據</returns>329     public byte ReadByte()330     {331         byte b = buf[readIndex];332         readIndex++;333         return b;334     }335 336     /// <summary>337     /// 讀取一個字節并轉為int類型的數據338     /// </summary>339     /// <returns>int數據</returns>340     public int ReadByteToInt()341     {342         byte b = ReadByte();343         return (int)b;344     }345 346     /// <summary>347     /// 獲取從index索引處開始len長度的字節348     /// </summary>349     /// <param name="index"></param>350     /// <param name="len"></param>351     /// <returns></returns>352     private byte[] Get(int index, int len)353     {354         byte[] bytes = new byte[len];355         Array.Copy(buf, index, bytes, 0, len);356         return flip(bytes);357     }358 359     /// <summary>360     /// 從讀取索引位置開始讀取len長度的字節數組361     /// </summary>362     /// <param name="len">待讀取的字節長度</param>363     /// <returns>字節數組</returns>364     private byte[] Read(int len)365     {366         byte[] bytes = Get(readIndex, len);367         readIndex += len;368         return bytes;369     }370 371     /// <summary>372     /// 讀取一個uint16數據373     /// </summary>374     /// <returns>ushort數據</returns>375     public ushort ReadUshort()376     {377         return BitConverter.ToUInt16(Read(2), 0);378     }379 380     /// <summary>381     /// 讀取一個int16數據382     /// </summary>383     /// <returns>short數據</returns>384     public short ReadShort()385     {386         return BitConverter.ToInt16(Read(2), 0);387     }388 389     /// <summary>390     /// 讀取一個uint32數據391     /// </summary>392     /// <returns>uint數據</returns>393     public uint ReadUint()394     {395         return BitConverter.ToUInt32(Read(4), 0);396     }397 398     /// <summary>399     /// 讀取一個int32數據400     /// </summary>401     /// <returns>int數據</returns>402     public int ReadInt()403     {404         return BitConverter.ToInt32(Read(4), 0);405     }406 407     /// <summary>408     /// 讀取一個uint64數據409     /// </summary>410     /// <returns>ulong數據</returns>411     public ulong ReadUlong()412     {413         return BitConverter.ToUInt64(Read(8), 0);414     }415 416     /// <summary>417     /// 讀取一個long數據418     /// </summary>419     /// <returns>long數據</returns>420     public long ReadLong()421     {422         return BitConverter.ToInt64(Read(8), 0);423     }424 425     /// <summary>426     /// 讀取一個float數據427     /// </summary>428     /// <returns>float數據</returns>429     public float ReadFloat()430     {431         return BitConverter.ToSingle(Read(4), 0);432     }433 434     /// <summary>435     /// 讀取一個double數據436     /// </summary>437     /// <returns>double數據</returns>438     public double ReadDouble()439     {440         return BitConverter.ToDouble(Read(8), 0);441     }442 443     /// <summary>444     /// 讀取一個字符445     /// </summary>446     /// <returns></returns>447     public char ReadChar()448     {449         return BitConverter.ToChar(Read(2), 0);450     }451 452     /// <summary>453     /// 讀取布爾型數據454     /// </summary>455     /// <returns></returns>456     public bool ReadBoolean()457     {458         return BitConverter.ToBoolean(Read(1), 0);459     }460 461     /// <summary>462     /// 從讀取索引位置開始讀取len長度的字節到disbytes目標字節數組中463     /// </summary>464     /// <param name="disbytes">讀取的字節將存入此字節數組</param>465     /// <param name="disstart">目標字節數組的寫入索引</param>466     /// <param name="len">讀取的長度</param>467     public void ReadBytes(byte[] disbytes, int disstart, int len)468     {469         int size = disstart + len;470         for (int i = disstart; i < size; i++)471         {472             disbytes[i] = this.ReadByte();473         }474     }475 476     /// <summary>477     /// 獲取一個字節478     /// </summary>479     /// <param name="index"></param>480     /// <returns></returns>481     public byte GetByte(int index)482     {483         return buf[index];484     }485 486     /// <summary>487     /// 獲取全部字節488     /// </summary>489     /// <returns></returns>490     public byte[] GetBytes()491     {492         return buf;493     }494 495     /// <summary>496     /// 獲取一個雙精度浮點數據,不改變數據內容497     /// </summary>498     /// <param name="index">字節索引</param>499     /// <returns></returns>500     public double GetDouble(int index)501     {502         return BitConverter.ToDouble(Get(0, 8), 0);503     }504 505     /// <summary>506     /// 獲取一個浮點數據,不改變數據內容507     /// </summary>508     /// <param name="index">字節索引</param>509     /// <returns></returns>510     public float GetFloat(int index)511     {512         return BitConverter.ToSingle(Get(0, 4), 0);513     }514 515     /// <summary>516     /// 獲取一個長整形數據,不改變數據內容517     /// </summary>518     /// <param name="index">字節索引</param>519     /// <returns></returns>520     public long GetLong(int index)521     {522         return BitConverter.ToInt64(Get(0, 8), 0);523     }524 525     /// <summary>526     /// 獲取一個整形數據,不改變數據內容527     /// </summary>528     /// <param name="index">字節索引</param>529     /// <returns></returns>530     public int GetInt(int index)531     {532         return BitConverter.ToInt32(Get(0, 4), 0);533     }534 535     /// <summary>536     /// 獲取一個短整形數據,不改變數據內容537     /// </summary>538     /// <param name="index">字節索引</param>539     /// <returns></returns>540     public int GetShort(int index)541     {542         return BitConverter.ToInt16(Get(0, 2), 0);543     }544 545 546     /// <summary>547     /// 清除已讀字節并重建緩存區548     /// </summary>549     public void DiscardReadBytes()550     {551         if (readIndex <= 0) return;552         int len = buf.Length - readIndex;553         byte[] newbuf = new byte[len];554         Array.Copy(buf, readIndex, newbuf, 0, len);555         buf = newbuf;556         writeIndex -= readIndex;557         markReadIndex -= readIndex;558         if (markReadIndex < 0)559         {560             markReadIndex = readIndex;561         }562         markWirteIndex -= readIndex;563         if (markWirteIndex < 0 || markWirteIndex < readIndex || markWirteIndex < markReadIndex)564         {565             markWirteIndex = writeIndex;566         }567         readIndex = 0;568     }569 570     /// <summary>571     /// 清空此對象,但保留字節緩存數組(空數組)572     /// </summary>573     public void Clear()574     {575         buf = new byte[buf.Length];576         readIndex = 0;577         writeIndex = 0;578         markReadIndex = 0;579         markWirteIndex = 0;580         capacity = buf.Length;581     }582     583     /// <summary>584     /// 釋放對象,清除字節緩存數組,如果此對象為可池化,那么調用此方法將會把此對象推入到池中等待下次調用585     /// </summary>586     public void Dispose()587     {588         readIndex = 0;589         writeIndex = 0;590         markReadIndex = 0;591         markWirteIndex = 0;592         if (isPool)593         {594             lock (pool)595             {596                 if (pool.Count < poolMaxCount)597                 {598                     pool.Add(this);599                 }600             }601         }602         else603         {604             capacity = 0;605             buf = null;606         }607     }608 609     /// <summary>610     /// 設置/獲取讀指針位置611     /// </summary>612     public int ReaderIndex613     {614         get615         {616             return readIndex;617         }618         set619         {620             if (value < 0) return;621             readIndex = value;622         }623     }624 625     /// <summary>626     /// 設置/獲取寫指針位置627     /// </summary>628     public int WriterIndex629     {630         get631         {632             return writeIndex;633         }634         set635         {636             if (value < 0) return;637             writeIndex = value;638         }639     }640 641     /// <summary>642     /// 標記讀取的索引位置643     /// </summary>644     public void MarkReaderIndex()645     {646         markReadIndex = readIndex;647     }648 649     /// <summary>650     /// 標記寫入的索引位置651     /// </summary>652     public void MarkWriterIndex()653     {654         markWirteIndex = writeIndex;655     }656 657     /// <summary>658     /// 將讀取的索引位置重置為標記的讀取索引位置659     /// </summary>660     public void ResetReaderIndex()661     {662         readIndex = markReadIndex;663     }664 665     /// <summary>666     /// 將寫入的索引位置重置為標記的寫入索引位置667     /// </summary>668     public void ResetWriterIndex()669     {670         writeIndex = markWirteIndex;671     }672 673     /// <summary>674     /// 可讀的有效字節數675     /// </summary>676     /// <returns>可讀的字節數</returns>677     public int ReadableBytes()678     {679         return writeIndex - readIndex;680     }681 682     /// <summary>683     /// 獲取可讀的字節數組684     /// </summary>685     /// <returns>字節數據</returns>686     public byte[] ToArray()687     {688         byte[] bytes = new byte[writeIndex];689         Array.Copy(buf, 0, bytes, 0, bytes.Length);690         return bytes;691     }692 693     /// <summary>694     /// 獲取緩存區容量大小695     /// </summary>696     /// <returns>緩存區容量</returns>697     public int GetCapacity()698     {699         return this.capacity;700     }701 702     /// <summary>703     /// 簡單的數據類型704     /// </summary>705     public enum LengthType706     {707         //byte類型708         BYTE,709         //short類型710         SHORT,711         //int類型712         INT713     }714 715     /// <summary>716     /// 寫入一個數據717     /// </summary>718     /// <param name="value">待寫入的數據</param>719     /// <param name="type">待寫入的數據類型</param>720     public void WriteValue(int value, LengthType type)721     {722         switch (type)723         {724             case LengthType.BYTE:725                 this.WriteByte(value);726                 break;727             case LengthType.SHORT:728                 this.WriteShort((short)value);729                 break;730             default:731                 this.WriteInt(value);732                 break;733         }734     }735 736     /// <summary>737     /// 讀取一個值,值類型根據type決定,int或short或byte738     /// </summary>739     /// <param name="type">值類型</param>740     /// <returns>int數據</returns>741     public int ReadValue(LengthType type)742     {743         switch (type)744         {745             case LengthType.BYTE:746                 return ReadByteToInt();747             case LengthType.SHORT:748                 return (int)ReadShort();749             default:750                 return ReadInt();751         }752     }753 754     /// <summary>755     /// 寫入一個字符串756     /// </summary>757     /// <param name="content">待寫入的字符串</param>758     /// <param name="lenType">寫入的字符串長度類型</param>759     public void WriteUTF8String(string content, LengthType lenType)760     {761         byte[] bytes = System.Text.UTF8Encoding.UTF8.GetBytes(content);762         int max;763         if (lenType == LengthType.BYTE)764         {765             WriteByte(bytes.Length);766             max = byte.MaxValue;767         }768         else if (lenType == LengthType.SHORT)769         {770             WriteShort((short)bytes.Length);771             max = short.MaxValue;772         }773         else774         {775             WriteInt(bytes.Length);776             max = int.MaxValue;777         }778         if (bytes.Length > max)779         {780             WriteBytes(bytes, 0, max);781         }782         else783         {784             WriteBytes(bytes, 0, bytes.Length);785         }786     }787 788     /// <summary>789     /// 讀取一個字符串790     /// </summary>791     /// <param name="len">需讀取的字符串長度</param>792     /// <returns>字符串</returns>793     public string ReadUTF8String(int len)794     {795         byte[] bytes = new byte[len];796         this.ReadBytes(bytes, 0, len);797         return System.Text.UTF8Encoding.UTF8.GetString(bytes);798     }799 800     /// <summary>801     /// 讀取一個字符串802     /// </summary>803     /// <param name="lenType">字符串長度類型</param>804     /// <returns>字符串</returns>805     public string ReadUTF8String(LengthType lenType)806     {807         int len = ReadValue(lenType);808         return ReadUTF8String(len);809     }810 811     /// <summary>812     /// 復制一個對象,具有與原對象相同的數據,不改變原對象的數據813     /// </summary>814     /// <returns></returns>815     public ByteBuffer Copy()816     {817         return Copy(0);818     }819 820     public ByteBuffer Copy(int startIndex)821     {822         if (buf == null)823         {824             return new ByteBuffer(16);825         }826         byte[] target = new byte[buf.Length - startIndex];827         Array.Copy(buf, startIndex, target, 0, target.Length);828         ByteBuffer buffer = new ByteBuffer(target.Length);829         buffer.WriteBytes(target);830         return buffer;831     }832 }

View Code

當然,c#中雖然沒有ByteBuffer,但也有拼接字節數組的方法,比如

      Send(          [] bytes =  [data.Length +          [] length = BitConverter.GetBytes(                                     Array.Copy(length, , bytes, ,          Array.Copy(data, , bytes,          mSocket.Send(bytes);
     }

字節數組拼接好后,就可以使用socket的send方法發送了,不過這一篇先繼續講完接收數據的處理

接收數據的順序是先接收消息長度,然后根據消息長度接收指定長度的消息

 1     void ReceiveMessage() 2     { 3           //上文說過,一個完整的消息是 消息長度+消息內容 4           //所以先創建一個長度4的字節數組,用于接收消息長度 5           byte[] recvBytesHead = GetBytesReceive(4); 6           //將消息長度字節組轉為int數值 7           int bodyLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(recvBytesHead, 0)); 8           //根據消息長度接收指定長度的字節組,這個字節組就是完整的消息內容 9           byte[] recvBytesBody = GetBytesReceive(bodyLength);10           //最后反序列化消息的內容11           Test message = ProtobufSerilizer.DeSerialize<Test>(messageBody);12     }

GetBytesRecive方法用于接收消息,并解決粘包、少包的問題,代碼如下

 1     /// <summary> 2     /// 接收數據并處理 3     /// </summary> 4     /// <param name="length"></param> 5     /// <returns></returns> 6     byte[] GetBytesReceive(int length) 7     { 8         //創建指定長度的字節組 9         byte[] recvBytes = new byte[length];10         //設置每次接收包的最大長度為1024個字節11         int packageMaxLength = 1024;12         //使用循環來保證接收的數據是完整的,如果剩余長度大于0,證明接收未完成13         while (length > 0)14         {15             //創建字節組,用于存放需要接收的字節流16             byte[] receiveBytes = new byte[length < packageMaxLength ? length : packageMaxLength];17             int iBytesBody = 0;18             //根據剩余需接收的長度來設置接收數據的長度19             if (length >= receiveBytes.Length)20                 iBytesBody = mSocket.Receive(receiveBytes, receiveBytes.Length, 0);21             else22                 iBytesBody = mSocket.Receive(receiveBytes, length, 0);23             receiveBytes.CopyTo(recvBytes, recvBytes.Length - length);24             //減去已接收的長度25             length -= iBytesBody;26         }27         return recvBytes;28     }

到這里,消息的簡單發送和接收就基本搞定了,但是,實際項目中,我們的消息數量肯定不會只有一條,如果是長鏈接的項目,更是需要一直接收和發送消息,該怎么辦?

unity的UI上的顯示只能在主線程中執行,可是如果我們在主線程一直接收和發送消息,那體驗將會極差,所以我們必須另外開啟線程來負責消息的接收和發送。

以上是“socket如何傳輸protobuf字節流”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

宣武区| 彰化市| 镇远县| 新和县| 平乡县| 石楼县| 和硕县| 梧州市| 邵东县| 当涂县| 乌海市| 浦北县| 隆子县| 昆明市| 墨江| 卢湾区| 安龙县| 锡林郭勒盟| 井陉县| 崇仁县| 瑞金市| 济源市| 衡山县| 双桥区| 平江县| 上林县| 瑞丽市| 泸西县| 临潭县| 全州县| 乌兰浩特市| 繁昌县| 简阳市| 横山县| 象州县| 政和县| 布尔津县| 盐边县| 清原| 鹤壁市| 思茅市|