//public static bool TryRead(this Stream stream, byte[] buffer, int offset, int count, out int bytesRead) //{ // bool successful = true; // int read = 0; // try // { // read = stream.Read(buffer, offset, count); // } // catch (Exception) // { // successful = false; // } // bytesRead = read; // return successful; //} //public static bool TryWrite(this Stream stream, byte[] buffer, int offset, int count) //{ // bool successful = true; // try // { // stream.Write(buffer, offset, count); // } // catch (Exception) // { // successful = false; // } // return successful; //} /// <summary> /// 从指定的 <see cref="System.IO.Stream"/> 中读取一条消息。 /// </summary> /// <param name="stream">要读取的 <see cref="System.IO.Stream"/>。</param> /// <param name="message">读取出的消息。如果返回值不是 <see cref="Kei.KNetwork.MessageIOErrorCode.NoError"/>,则该值无效。</param> /// <returns>一个 <see cref="Kei.KNetwork.MessageIOCode"/> 值,表示读取的结果。</returns> public static MessageIOErrorCode ReadMessage(this Stream stream, out KMessage message) { byte[] buffer; KMessage km = new KMessage(); // Check magic try { buffer = new byte[8]; stream.Read(buffer, 0, 8); km.MagicNumber = BitConverter.ToUInt64(buffer, 0); if (km.MagicNumber != KMessage.Magic) { message = km; return(MessageIOErrorCode.WrongMagicNumber); } } catch (Exception) { message = km; return(MessageIOErrorCode.ReadMagicNumberFailed); } // Read header try { var headerSize = Marshal.SizeOf(typeof(KMessageHeader)); buffer = new byte[headerSize]; stream.Read(buffer, 0, headerSize); km.Header = KMessageHeader.FromByteArray(buffer); } catch (Exception) { message = km; return(MessageIOErrorCode.ReadHeaderFailed); } // Read content try { KMessageContent content = new KMessageContent(); buffer = new byte[4]; stream.Read(buffer, 0, 4); content.DataLength = BitConverter.ToUInt32(buffer, 0); content.Data = new byte[content.DataLength]; if (content.DataLength > 0) { stream.Read(content.Data, 0, (int)content.DataLength); } km.Content = content; } catch (Exception) { message = km; return(MessageIOErrorCode.ReadContentFailed); } message = km; return(MessageIOErrorCode.NoError); }
/// <summary> /// 生成一个 ClientEnterNetwork 消息。 /// </summary> /// <param name="localEP">消息源的端点。</param> /// <param name="realPort">非零表示这是接入点要连接接入点,该端口是本机正在监听的端口;零表示只是普通用户连接接入点。</param> /// <returns>创建的 ClientEnterNetwork 消息。</returns> public static KMessage ClientEnterNetwork(KEndPoint localEP, ushort realPort) { var message = KMessage.CreateEmptyMessage(); message.Header.Code = KMessageCode.ClientEnterNetwork; message.Header.SourceEndPoint = localEP; message.Header.MessageID = GetMessageHash(); BEncodedDictionary data = new BEncodedDictionary(); data.Add("message handled", 0); data.Add("real port", realPort); message.Content = KMessageContent.FromByteArray(data.Encode()); return(message); }
/// <summary> /// 生成一个 GotPeer 消息。 /// </summary> /// <param name="localEP">消息源的端点。</param> /// <param name="infoHash">用户所持有的 InfoHash。</param> /// <param name="bitTorrentClientPort">用户所监听的端口(即 BitTorrent 客户端的监听端口)。</param> /// <returns>创建的 GotPeer 消息。</returns> public static KMessage GotPeer(KEndPoint localEP, InfoHash infoHash, ushort bitTorrentClientPort) { var message = KMessage.CreateEmptyMessage(); message.Header.Code = KMessageCode.GotPeer; message.Header.SourceEndPoint = localEP; message.Header.MessageID = GetMessageHash(); BEncodedDictionary data = new BEncodedDictionary(); data.Add("infohash", infoHash.ToByteArray()); data.Add("bt client port", bitTorrentClientPort); message.Content = KMessageContent.FromByteArray(data.Encode()); return(message); }