public BencodeNET.Torrents.Torrent DecodeTorrent(string torrentPath) { BencodeNET.Parsing.BencodeParser parser = new BencodeNET.Parsing.BencodeParser(); return(parser.Parse <BencodeNET.Torrents.Torrent>(torrentPath)); }
public static void StartServer() { Debug.Log("nrepl: starting"); running = true; new Thread(() => { var listener = new TcpListener(IPAddress.Loopback, Port); try { // TODO make IPAddress.Loopback configurable to allow remote connections listener.Start(); Debug.LogFormat("nrepl: listening on port {0}", Port); while (running) { if (!listener.Pending()) { Thread.Sleep(100); continue; } var client = listener.AcceptTcpClient(); new Thread(() => { Debug.LogFormat("nrepl: connected to client {0}", client.Client.RemoteEndPoint); var parser = new BencodeNET.Parsing.BencodeParser(); var clientRunning = true; var buffer = new byte[1024 * 8]; // 8k buffer while (running && clientRunning) { // bencode needs a seekable stream to parse, so each // message gets its own MemoryStream (MemoryStreams are // seekable, NetworkStreams e.g. client.GetStream() are not) try { using (var ms = new MemoryStream()) { // message might be bigger than our buffer // loop till we have the whole thing var parsedMessage = false; while (!parsedMessage) { // copy from network stream into memory stream var total = client.GetStream().Read(buffer, 0, buffer.Length); if (total == 0) { // reading zero bytes after blocking means the other end has hung up clientRunning = false; break; } ms.Write(buffer, 0, total); // bencode parsing expects stream position to be 0 ms.Position = 0; try { // try and parse the message and handle it var obj = parser.Parse(ms); parsedMessage = true; var message = obj as BDictionary; if (message != null) { try { HandleMessage(message, client); } catch (Exception e) { Debug.LogException(e); } } } catch (InvalidBencodeException <BDictionary> e) { if (Encoding.UTF8.GetString(ms.GetBuffer()) .Contains("2:op13:init-debugger")) { // hack to deal with cider sending us packets with duplicate keys // BencodeNET cannot deal with duplicate keys, hence the string check // the real solution is to switch to the bencode implementation that // nrepl itself uses parsedMessage = true; } else { // most likely an incomplete message. i kind // of wish this was an EOF exception... we cannot // actually tell the difference between an incomplete // message and an invalid one as it stands // seek to the end of the MemoryStream to take on more bytes ms.Seek(0, SeekOrigin.End); } } } } } catch (SocketException e) { // the other end has disconnected, gracefully shutdown clientRunning = false; } catch (IOException e) { // the other end has disconnected, gracefully shutdown clientRunning = false; } catch (ObjectDisposedException e) { // the other end has disconnected, gracefully shutdown clientRunning = false; } catch (Exception e) { Debug.LogWarningFormat("nrepl: {0}", e); clientRunning = false; } } Debug.LogFormat("nrepl: disconnected from client {0}", client.Client.RemoteEndPoint); client.Close(); client.Dispose(); }).Start(); } } catch (ThreadAbortException) { // do nothing. this probably means the VM is being reset. } catch (Exception e) { Debug.LogException(e); } finally { Debug.LogFormat("nrepl: closing port {0}", Port); listener.Stop(); } }).Start(); }