using System; using System.IO; using System.Net; using System.Net.Sockets; using System.Diagnostics; namespace Lumpio.Net.Msn { class MsnConnectionHandler { private Socket sock = null; private MemoryStream stream = null; private UInt32 trid = 1; private string cmdcode; private UInt32 cmdtrid; private int payloadleft = 0; private string[] args; private IPEndPoint ep; public void Connect(IPEndPoint ep) { this.ep = ep; if (sock != null) { sock.Shutdown(SocketShutdown.Both); sock.Close(); } sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); sock.Connect(ep); sock.Blocking = false; if (stream == null) { stream = new MemoryStream(); } else { stream.SetLength(0); } } public MsnCommand PollCommand() { try { while (sock.Available > 0) { byte[] buffer = new byte[1]; sock.Receive(buffer); if (payloadleft > 0) { stream.WriteByte(buffer[0]); payloadleft--; if (payloadleft == 0) { MsnCommand cmd = new MsnCommand(cmdcode, cmdtrid, args, stream.ToArray()); //stream.SetLength(0); FileStream f = File.Open("thelog", FileMode.Append, FileAccess.Write); //f.Write(System.Text.Encoding.UTF8.GetBytes("--- PAYLOAD BOUNDARY ---\r\n")); f.Write(stream.ToArray(), 0, (int)stream.Length); f.Write(System.Text.Encoding.UTF8.GetBytes("\r\n--------------\r\n"), 0, 18); f.Close(); stream.SetLength(0); //Debug.WriteLine("<<< " + cmd.ToString()); Debug.WriteLine(cmd.Payload); Debug.WriteLine("=== END OF PAYLOAD ==="); return cmd; } } else { if (buffer[0] == '\n') { string cmd = System.Text.Encoding.UTF8.GetString(stream.ToArray()); stream.SetLength(0); bool hastrid = false; bool ispayload = false; string[] parts = cmd.Split(' '); switch (parts[0]) { case "VER": case "CVR": case "XFR": case "USR": case "SYN": case "CHL": case "QRY": case "ANS": case "IRO": case "ILN": case "ACK": case "NAK": hastrid = true; break; case "MSG": case "UBX": case "GCF": ispayload = true; break; } if (parts.Length > 0) { args = new string[parts.Length - 1 - (hastrid ? 1 : 0) - (ispayload ? 1 : 0)]; Array.Copy(parts, (hastrid ? 2 : 1), args, 0, args.Length); } else { args = null; } cmdcode = parts[0]; cmdtrid = hastrid ? UInt32.Parse(parts[1]) : 0; if (!ispayload) { Debug.WriteLine("<<< " + cmd); return new MsnCommand(cmdcode, cmdtrid, args, null); } else { Debug.WriteLine("<<< " + cmd + " "); payloadleft = Int32.Parse(parts[parts.Length - 1]); } } else if (buffer[0] != '\r') { stream.WriteByte(buffer[0]); } } } } catch (SocketException e) { } catch (ObjectDisposedException e) { } return null; } public void SendBytes(byte[] bytes) { try { sock.Send(bytes); } catch (SocketException e) { Connect(ep); sock.Send(bytes); } } public void SendCommand(string cmd) { Debug.WriteLine(">>> " + cmd); byte[] cmdbytes = System.Text.Encoding.UTF8.GetBytes(cmd + "\r\n"); SendBytes(cmdbytes); } public void SendPayloadCommand(string cmd, string payload) { byte[] payloadbytes = System.Text.Encoding.UTF8.GetBytes(payload); Debug.WriteLine(">>> " + cmd + "<" + payloadbytes.Length + " BYTES PAYLOAD DATA>"); Debug.WriteLine(payload); Debug.WriteLine("=== END OF PAYLOAD ==="); byte[] cmdbytes = System.Text.Encoding.UTF8.GetBytes(cmd + " " + payloadbytes.Length + "\r\n"); SendBytes(cmdbytes); SendBytes(payloadbytes); } /*public void SendBinaryPayloadCommand(string cmd, string headers, byte[] binary) { byte[] payloadbytes = System.Text.Encoding.UTF8.GetBytes(payload); Debug.WriteLine(">>> " + cmd + "<" + payloadbytes.Length + " BYTES PAYLOAD DATA>"); Debug.WriteLine(payload); Debug.WriteLine("=== END OF PAYLOAD ==="); byte[] cmdbytes = System.Text.Encoding.UTF8.GetBytes(cmd + " " + payloadbytes.Length + "\r\n"); sock.Send(cmdbytes); sock.Send(payloadbytes); }*/ public void Close() { sock.Shutdown(SocketShutdown.Both); sock.Close(); } public UInt32 GetTrID() { if (trid >= 10000) { trid = 1; } return trid++; } } }