/// <summary> /// Crafts a CedLibContentheader and returns it as string. /// </summary> /// <param name="cHeader">The CedLibContentHeader to parse</param> /// <returns></returns> public static string MakeCedLibHeaderString(CedLibContentheader cHeader) { StringBuilder sbuilder = new StringBuilder(); sbuilder.AppendFormat("Contentheader:{0}\n", cHeader.ContentType); sbuilder.AppendFormat("CedLibProtVersion|:{0}\n", cHeader.CedLibProtocolVersion); sbuilder.AppendFormat("Contentlength|:{0}\n", cHeader.ContentLength); sbuilder.AppendFormat("FileSum|:{0}\n", cHeader.FileSum); sbuilder.AppendFormat("FileName|:{0}\n", cHeader.FileName); return sbuilder.ToString(); }
public static void sendcontentheader(Socket bacon, CedLibContentheader cHeader) { StringBuilder sbuilder = new StringBuilder(); sbuilder.AppendFormat("Contentheader:{0}\n", cHeader.ContentType); sbuilder.AppendFormat("CedLibProtVersion|:{0}\n", cHeader.CedLibProtocolVersion); sbuilder.AppendFormat("Contentlength|:{0}\n", cHeader.ContentLength); sbuilder.AppendFormat("FileSum|:{0}\n", cHeader.FileSum); sbuilder.AppendFormat("FileName|:{0}\n", cHeader.FileName); sendstring(bacon, sbuilder.ToString()); }
/// <summary> /// Receives a file using the CedLib protocol. (sender must be using CedLib.Networking.sendfile) /// </summary> /// <param name="bacon">The socket to use, will be disconnected after file is received, but can be reused.</param> /// <param name="FileInfo">The file to save to.</param> /// <param name="contentheader">The CedLib content header as received from the remote party.</param> /// <param name="Console">The CedLib formConsole to spam info to while transferring.</param> public static void receivefile(Socket bacon, FileInfo FileInfo, CedLibContentheader contentheader, formConsole Console) { int chunksize = Globals.chunksize * 1024; Console.WriteLine("Chunksize is set to " + chunksize); byte[] receivebytes = new byte[chunksize]; //If done initializing stuff for the receive, send 'OK!' to signal the start of the transfer Console.WriteLine("Sending response to header"); sendstring(bacon, "OK!\n Continue to send me the file"); if (!waitfordata(bacon, 30000, Console)) throw new Exception("Time out while waiting for sender to begin transfer."); BinaryWriter bwriter = new BinaryWriter(File.Open(FileInfo.FullName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read)); System.Diagnostics.Stopwatch swatch = new System.Diagnostics.Stopwatch(); swatch.Start(); Console.Write(string.Format("Receiving file from {0}..", bacon.RemoteEndPoint)); long receivedcount = 0; int lastreceive = 1; while (lastreceive > 0 && bacon.Connected && receivedcount <= contentheader.ContentLength) { if (bacon.Connected) lastreceive = bacon.Receive(receivebytes, chunksize, SocketFlags.None); else { Console.Write("Remote party disconnected. "); break; } bwriter.Write(receivebytes, 0, lastreceive); bwriter.Flush(); Console.Write("."); receivedcount += lastreceive; } bwriter.Flush(); bwriter.Close(); bool verified = false; swatch.Stop(); bacon.Shutdown(SocketShutdown.Both); bacon.Disconnect(true); Console.WriteLine("Done, verifying MD5.."); if (contentheader.FileSum != "") { string newsum = misc_usefulfunctions.GetMD5HashFromFile(FileInfo.FullName); if (newsum != contentheader.FileSum) throw new Exception(string.Format("File corrupted during transfer! Expected sum {0} But got sum {1}", contentheader.FileSum, newsum)); verified = true; } else Console.WriteLine("Warning: No MD5 summary found in content header, cannot verify data!"); float speedinKB = ((receivedcount / 1024.0f) / (swatch.ElapsedMilliseconds / 1000.0f)); if (verified) Console.WriteLine(string.Format("Verified MD5!\nSummary: received {0} bytes in {1} milliseconds! ({2}KB/s)", new object[] { receivedcount, swatch.ElapsedMilliseconds, speedinKB })); else Console.WriteLine(string.Format("Summary: received {0} bytes in {1} milliseconds! ({2}KB/s)", new object[] { receivedcount, swatch.ElapsedMilliseconds, speedinKB })); }
/// <summary> /// Parses the CedLib Content header.. /// </summary> /// <param name="header">The header string as given by the remote endpoint.</param> /// <returns>An instant of the CedLibContentheader class.</returns> public static CedLibContentheader ParseContentHeader(string header) { CedLibContentheader returnheader = new CedLibContentheader(); if (header.StartsWith("Contentheader")) { foreach (string line in header.Split('\n')) { if (line.StartsWith("Contentheader")) if (!Enum.TryParse<CedLibContenttype>(line.Split(':')[1], out returnheader.ContentType)) throw new Exception(string.Format("Failed to parse Contentheader type.\nAnyone heard what {0} is? Cause i haven't o3o", line.Split(':'))); if (line.StartsWith("CedLibProtVersion|:")) { CedLibProtocolVersion protver = new CedLibProtocolVersion(); if (Enum.TryParse<CedLibProtocolVersion>(line.Split(':')[1], out protver)) returnheader.CedLibProtocolVersion = protver; else returnheader.CedLibProtocolVersion = CedLibProtocolVersion.UNKNOWN; } if (line.StartsWith("Contentlength|:")) { long contlength = 0; if (!long.TryParse(line.Split(':')[1], out contlength)) throw new Exception(string.Format("Failed to parse Contentlength!\nCouldn't parse {0} to integer", line.Split(':')[1])); returnheader.ContentLength = contlength; } if (line.StartsWith("FileSum|:")) { returnheader.FileSum = line.Split(':')[1]; } if (line.StartsWith("FileName|:")) { returnheader.FileName = line.Split(':')[1]; } } } else throw new Exception("Content header provided is not a valid CedLib content header."); return returnheader; }
/// <summary> /// Receives bytes from a remote party and puts them in a memory stream. (as opposed to a file) /// </summary> /// <param name="bacon">Socket to receive from</param> /// <param name="cHeader">CedLib contentheader (needed for bytescount)</param> /// <param name="Console">The CedLib formConsole to spam relevant info to.</param> /// <returns>Memorystream filled with bytes from remote party.</returns> public static MemoryStream receivebytes(Socket bacon, CedLibContentheader cHeader, formConsole Console) { MemoryStream memstream = new MemoryStream(); int chunksize = 1024 * 1024; byte[] receivebytes = new byte[chunksize]; //If done initializing stuff for the receive, send 'OK!' to signal the start of the transfer Console.WriteLine("Sending response to header"); sendstring(bacon, "OK!\n Continue to send me the bytes"); if (!waitfordata(bacon, 30000, Console)) throw new Exception("Time out while waiting for sender to begin transfer."); System.Diagnostics.Stopwatch swatch = new System.Diagnostics.Stopwatch(); swatch.Start(); Console.Write("Receiving file.."); long receivedcount = 0; int lastreceive = 1; while (lastreceive > 0 && bacon.Connected && receivedcount <= cHeader.ContentLength) { if (bacon.Connected) lastreceive = bacon.Receive(receivebytes, chunksize, SocketFlags.None); else { Console.Write("Remote party disconnected. "); break; } memstream.Write(receivebytes, 0, lastreceive); Console.Write("."); receivedcount += lastreceive; } swatch.Stop(); bacon.Shutdown(SocketShutdown.Both); bacon.Disconnect(true); float speedinKB = ((receivedcount / 1024.0f) / (swatch.ElapsedMilliseconds / 1000.0f)); Console.WriteLine(string.Format("Done! received {0} bytes in {1} milliseconds! ({2}KB/s)", new object[] { receivedcount, swatch.ElapsedMilliseconds, speedinKB })); return memstream; }