byte[] getBinaryMessage(P2PMessage p2PMessage) { MemoryStream ms = new MemoryStream(); serializer.Serialize(ms, p2PMessage); byte[] send_buffer = ms.ToArray(); return(send_buffer); }
static void serializeAndWrite(P2PMessage p2PMessage) { string path = @"C:\Users\ayanamists\source\repos\P2PDownload\P2PDownload\test"; var stream = new MemoryStream(); var serializer = new BinarySerializer(); serializer.Serialize(stream, p2PMessage); WriteToFile($"{path}\\{p2PMessage.type}", stream.ToArray()); }
public static List<P2PMessage> GenFromMS(MemoryStream ms) { var now_pos = 0; List<P2PMessage> ret = new List<P2PMessage>(); var max_pos = ms.Position; ms.Position = 0; while (now_pos < max_pos) { var buffer_head = new byte[8]; ms.Read(buffer_head, 0, 8); var length = BitConverter.ToInt32(buffer_head, 4); var type_value = BitConverter.ToInt32(buffer_head); var buffer_tail = new byte[length]; ms.Read(buffer_tail, 0, length); var now_item = new P2PMessage(); switch (type_value) { case 0: now_item = new GetDataMessage(buffer_tail); break; case 1: now_item = new GetFileInfoMessage(buffer_tail); break; case 2: now_item = new GetBlockInfoMessage(buffer_tail); break; case 3: now_item = new DataMessage(buffer_tail); break; case 4: now_item = new ErrorMessage(buffer_tail); break; case 5: now_item = new FileInfoMessage(buffer_tail); break; case 6: now_item = new BlockInfoMessage(buffer_tail); break; case 7: now_item = new OKMessage(buffer_tail); break; case 8: now_item = new CloseMessage(); break; case 9: now_item = new AliveMessage(); break; default: throw new System.Exception("not allow"); } now_item.type = (P2PMessageType)type_value; ret.Add(now_item); now_pos += 8 + length; } Debug.Assert(now_pos == max_pos); return ret; }
static void TestParse(P2PMessage p2PMessage) { string path = @"C:\Users\ayanamists\source\repos\P2PDownload\P2PDownload\test"; var i = ReadFromFile($"{path}\\{p2PMessage.type}"); var r = P2PMessage.GenFromBuffer(i.Item1, i.Item2); var stream = new MemoryStream(); var serializer = new BinarySerializer(); serializer.Serialize(stream, p2PMessage); WriteToFile($"{path}\\{p2PMessage.type}-2", stream.ToArray()); }
void ReadToBuffer(int maxMessage) { var s = tcpCilent.GetStream(); // 调节缓冲区大小,修改此变量 var buffer_size = 5000; var buffer = new byte[buffer_size]; var length4Read = -1; var count = 0; var size = 0; while (count < maxMessage) { tcpCilent.ReceiveTimeout = 80; try { do { if (length4Read == -1) { size = s.Read(buffer, 0, 8); length4Read = P2PMessage.TryParseHeader(buffer); } else if (length4Read == 0) { count++; length4Read = -1; break; } else { var read_size = (length4Read > buffer_size) ? buffer_size : length4Read; size = s.Read(buffer, 0, read_size); length4Read -= size; } _logger.Info($"read {size} bytes from socket, length for read is {length4Read}"); ms.Write(buffer, 0, size); } while (s.DataAvailable); } catch (IOException) { _logger.Info($"Recive timeout"); break; } } }
public List <P2PMessage> GetReply(int maxReplyMessage) { ReadToBuffer(maxReplyMessage); return(P2PMessage.GenFromMS(ms)); }
void send(P2PMessage message) { _logger.Info($"send {message.type}, length {message.length}"); send(getBinaryMessage(message)); }
static void send(P2PMessage message, TcpClient client) { _logger.Info($"send {message.type}"); send(getBinaryMessage(message), client); }
void handleLoop(TcpClient client) { System.Timers.Timer t = new System.Timers.Timer(200); var s = client.GetStream(); bool ifClose = false; Stopwatch stopwatch = new Stopwatch(); var continueTime = 0L; bool ifAlive = true; while (!ifClose && client.Connected) { if (continueTime > 500) { if (ifAlive) { continueTime = 0; ifAlive = false; } else { ifClose = true; break; } } stopwatch.Start(); try { _logger.Info("enter loop"); var waitConstant = 1; var count = 0; var ms = new MemoryStream(); var length4Read = -1; while (count < waitConstant) { client.ReceiveTimeout = 100; // 如果想要调节缓冲区大小,修改此变量 var buffer_size = 5000; var buffer = new byte[buffer_size]; var size = 0; do { if (length4Read == 0) { count++; break; } else if (length4Read == -1) { size = s.Read(buffer, 0, 8); length4Read = P2PMessage.TryParseHeader(buffer); if (BitConverter.ToInt32(buffer) == (int)P2PMessageType.GET_OK) { waitConstant = 2; } else { waitConstant = 1; } } else { var read_size = (length4Read > buffer_size) ? buffer_size : length4Read; size = s.Read(buffer, 0, read_size); length4Read = length4Read - size; } ms.Write(buffer, 0, size); _logger.Info($"now recv buffer is {BitConverter.ToString(ms.ToArray())}, length for read is {length4Read}, count is {count}"); } while (s.DataAvailable); } var what = P2PMessage.GenFromMS(ms); foreach (var i in what) { ifAlive = true; _logger.Info($"recive message : {i.type}"); if (i.type == P2PMessageType.GET_FILE_INFO) { var hash = ((GetFileInfoMessage)i).hash; // 在这里,我使用绑定到TCP四元组的本机地址作为传回的本机地址。 var localAddress = ((IPEndPoint)client.Client.RemoteEndPoint).Address; SendFileInfoMessage(fmanager.ProvideLocateInfo(hash, localAddress), hash, client); } else if (i.type == P2PMessageType.GET_DATA) { var message = (GetDataMessage)i; var hash = message.hash; var indexs = message.what; byte[] send_buffer; try { foreach (var index in indexs) { send_buffer = fmanager.ProvideFileData(hash, index); send(new DataMessage(send_buffer, hash, index), client); } } catch (BlockNotPresentException) { send(new ErrorMessage(hash, indexs[0]), client); } } else if (i.type == P2PMessageType.GET_OK) { var message = (OKMessage)i; var remote_ip = ((IPEndPoint)client.Client.RemoteEndPoint).Address; fmanager.SetRemoteBlockPresentStat( message.block.hashOfFile, remote_ip, message.block.index, true); } else if (i.type == P2PMessageType.CLOSE) { ifClose = true; } } } catch (IOException) { _logger.Debug($"timeout for receive : {client.Client.RemoteEndPoint}"); break; } stopwatch.Stop(); continueTime += stopwatch.ElapsedMilliseconds; } }