using System; using System.Collections; using System.Net.Sockets; using System.Diagnostics; using System.Net; using System.IO; using System.Text; // Filename: Socket.cs // Author:Sean Kessler namespace IPMonitor { internal class ContentHeader { private String server; private String date; private String pragma; private String connection; private String contentLength; private String contentType; private String cookie; private String cache; public ContentHeader() { } public String Server { get { return server; } set { server = value; } } public String Date { get { return date; } set { date = value; } } public String Pragma { get { return pragma; } set { pragma = value; } } public String Connection { get { return connection; } set { connection = value; } } public String ContentLength { get { return contentLength; } set { contentLength = value; } } public String ContentType { get { return contentType; } set { contentType = value; } } public String Cookie { get { return cookie; } set { cookie = value; } } public String Cache { get { return cache; } set { cache = value; } } } public class SocketConnector : TcpClient { public SocketConnector(Socket serverSocket) { Client = serverSocket; } } public class ServerSocketControl { private Socket acceptSocket; private IPEndPoint ipLocalEndPoint; public ServerSocketControl(int port) { int index; acceptSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); acceptSocket.ReceiveTimeout = -1; IPHostEntry hostEntry = Dns.GetHostEntry(Dns.GetHostName()); IPAddress ipAddress = null; for (index = 0; index < hostEntry.AddressList.Length; index++) { if (IPAddress.TryParse(hostEntry.AddressList[index].ToString(), out ipAddress)) { switch (ipAddress.AddressFamily) { case System.Net.Sockets.AddressFamily.InterNetwork: break; case System.Net.Sockets.AddressFamily.InterNetworkV6: ipAddress = null; break; default: ipAddress = null; break; } if (null != ipAddress) break; } } if (null == ipAddress) throw new Exception("Could not determine IPV4 address."); ipLocalEndPoint = new IPEndPoint(ipAddress, port); SocketControl.TraceOut("[ServerSocketControl] Binding to endpoint " + ipLocalEndPoint); acceptSocket.Bind(ipLocalEndPoint); SocketControl.TraceOut("[ServerSocketControl] socket bound"); acceptSocket.Listen(-1); } public ServerSocketControl() { int index; acceptSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); acceptSocket.ReceiveTimeout = -1; IPHostEntry hostEntry = Dns.GetHostEntry(Dns.GetHostName()); IPAddress ipAddress = null; for (index = 0; index < hostEntry.AddressList.Length; index++) { if (IPAddress.TryParse(hostEntry.AddressList[index].ToString(), out ipAddress)) { switch (ipAddress.AddressFamily) { case System.Net.Sockets.AddressFamily.InterNetwork: break; case System.Net.Sockets.AddressFamily.InterNetworkV6: ipAddress = null; break; default: ipAddress = null; break; } if (null != ipAddress) break; } } if (null == ipAddress) throw new Exception("Could not determine IPV4 address."); ipLocalEndPoint = new IPEndPoint(ipAddress, 0); SocketControl.TraceOut("[ServerSocketControl] Binding to endpoint " + ipLocalEndPoint); acceptSocket.Bind(ipLocalEndPoint); SocketControl.TraceOut("[ServerSocketControl] socket bound"); acceptSocket.Listen(-1); ipLocalEndPoint = (IPEndPoint)acceptSocket.LocalEndPoint; } public IPEndPoint LocalEndPoint() { return ipLocalEndPoint; } public IPAddress Address() { return ipLocalEndPoint.Address; } public int Port() { return ipLocalEndPoint.Port; } public void Close() { if (null == acceptSocket) return; acceptSocket.Shutdown(SocketShutdown.Both); acceptSocket.Close(); acceptSocket = null; } public SocketControl Accept() { Socket socket = acceptSocket.Accept(); ipLocalEndPoint = (IPEndPoint)socket.LocalEndPoint; SocketControl.TraceOut("[ServerSocketControl::Accept] connect accepted on " + ipLocalEndPoint); SocketConnector socketConnector = new SocketConnector(socket); return new SocketControl(socketConnector); } } public class SocketControl { public const int OkResult = 220; public const int ErrorResult = 500; private TcpClient tcpClient; private NetworkStream networkStream; private BinaryWriter binaryWriter; private BinaryReader binaryReader; private bool isConnected = false; public SocketControl(SocketConnector socketConnector) { tcpClient = socketConnector; tcpClient.LingerState = new LingerOption(false, 0); tcpClient.ReceiveTimeout = -1; networkStream = tcpClient.GetStream(); binaryWriter = new BinaryWriter(networkStream); binaryReader = new BinaryReader(networkStream); isConnected = true; } public SocketControl(String strHost, int port) { tcpClient = new TcpClient(); tcpClient.Connect(strHost, port); tcpClient.LingerState = new LingerOption(false, 0); tcpClient.ReceiveTimeout = -1; networkStream = tcpClient.GetStream(); binaryWriter = new BinaryWriter(networkStream); binaryReader = new BinaryReader(networkStream); isConnected = true; } public void Close() { if (!isConnected) return; isConnected = false; binaryWriter.Close(); binaryWriter = null; binaryReader.Close(); binaryReader = null; tcpClient.Close(); tcpClient = null; } public string ReadLine() { StringBuilder strLine = new StringBuilder(); if (!isConnected) return null; byte[] streamByte = new byte[1]; while (true) { binaryReader.Read(streamByte, 0, 1); if (13 == streamByte[0]) continue; else if (10 == streamByte[0]) break; else if ('\0' == (char)streamByte[0]) break; strLine.Append((char)streamByte[0]); streamByte[0] = 0; } return strLine.ToString(); } public bool WriteLine(string strLine) { if (!isConnected || 0 == strLine.Length) return false; strLine += "\r\n"; char[] streamData = strLine.ToCharArray(); binaryWriter.Write(streamData); binaryWriter.Flush(); return true; } public int GetResultCode(string strLine) { if (0 == strLine.Length) return 0; string strResult = ""; int strIndex = 0; while (true) { if (strIndex >= 3) break; if (' ' == strLine[strIndex]) break; strResult += strLine[strIndex]; strIndex++; } if (0 == strResult.Length) return 0; return int.Parse(strResult); } public string GetResult(string strLine) { string strResult = ""; int strIndex = 0; int strLength = strLine.Length; if (0 == strLength) return strResult; while (' ' != strLine[strIndex] && strIndex < strLength) strIndex++; strIndex++; if (strIndex >= strLength) return strResult; while (strIndex < strLength) { strResult += strLine[strIndex]; strIndex++; } return strResult; } public char[] GetRequest(string strRequest, int max) { if (!isConnected || null == strRequest || 0 == max) return null; WriteLine("GET " + strRequest); return Receive(max); } public MemoryStream GetRequest(string strRequest) { if (!isConnected || null == strRequest) return null; WriteLine("GET " + strRequest); return Receive(); } public String GetRequestToString(String strRequest) { if (!isConnected || null == strRequest) return null; WriteLine("GET " + strRequest); MemoryStream memoryStream = Receive(); memoryStream.Seek(0, SeekOrigin.Begin); StreamReader streamReader = new StreamReader(memoryStream); String strResponse = streamReader.ReadToEnd(); streamReader.Close(); memoryStream.Close(); return strResponse; } public bool Write(char[] chars) { if (!isConnected || null == chars || 0 == chars.Length) return false; binaryWriter.Write(chars); binaryWriter.Flush(); return true; } public bool Write(byte[] bytes) { if (!isConnected || null == bytes || 0 == bytes.Length) return false; binaryWriter.Write(bytes); binaryWriter.Flush(); return true; } public bool Write(byte[] bytes, int length) { if (!isConnected || null == bytes || 0 == bytes.Length) return false; binaryWriter.Write(bytes, 0, length); binaryWriter.Flush(); return true; } public int ReadInt() { char[] chars = new char[4]; Receive(chars); return (((byte)chars[3]) << 24) | (((byte)chars[2]) << 16) + (((byte)chars[1]) << 8) + ((byte)chars[0]); } public bool IsConnected() { return isConnected; } public bool Receive(char[] streamChars) { byte[] cb; int count = 0; int max; int readCount; max = streamChars.Length; if (!isConnected || 0 == max) return false; cb = new byte[1]; while (true) { readCount = binaryReader.Read(cb, 0, 1); if (0 == readCount) break; streamChars[count++] = (char)cb[0]; if (count >= max) break; } return count == max; } public int Receive(ref byte[] streamBytes) { int count = 0; int max; int readLength = 0; max = streamBytes.Length; if (!isConnected || 0 == max) return count; while (true) { readLength = binaryReader.Read(streamBytes, count, max - count); if (0 == readLength) break; count += readLength; if (count >= max) break; } if (0 == count) return count; byte[] stream = new byte[count]; Array.Copy(streamBytes, stream, count); streamBytes = stream; return count; } public char[] Receive(int maxChars) { char[] streamChar; char[] stream; byte[] cb; int count = 0; int readCount = 0; if (!isConnected || 0 == maxChars) return null; streamChar = new char[maxChars]; while (true) { cb = new byte[1]; readCount = binaryReader.Read(cb, 0, 1); if (0 == readCount) break; streamChar[count++] = (char)cb[0]; if (count >= maxChars) break; } stream = new char[count]; Array.Copy(streamChar, stream, count); return stream; } public MemoryStream Receive() { MemoryStream memoryStream = new MemoryStream(); byte[] cb; int readCount = 0; if (!isConnected) return null; while (true) { cb = new byte[1]; readCount = binaryReader.Read(cb, 0, 1); if (0 == readCount) break; memoryStream.WriteByte(cb[0]); } memoryStream.Seek(0, SeekOrigin.Begin); return memoryStream; } public bool Receive(ArrayList receiveStrings, ArrayList responseStrings) { bool isInMultiLine = false; bool returnCode = true; string seriesItem = ""; string stringData = ""; receiveStrings.Clear(); if (!isConnected) return false; while (true) { stringData = ReadLine(); if (null == stringData || 0 == stringData.Length) break; if (0 == receiveStrings.Count) { seriesItem = stringData.Substring(0, 3); if (!IsInResponse(seriesItem, responseStrings)) { returnCode = false; receiveStrings.Add(stringData); break; } if ('-' == stringData[3]) isInMultiLine = true; } if (0 != receiveStrings.Count && isInMultiLine && '-' != stringData[3] && stringData.Substring(0, 3).Equals(seriesItem)) { receiveStrings.Add(stringData); break; } receiveStrings.Add(stringData); if (!isInMultiLine) break; } return returnCode; } public bool Receive(ArrayList receiveStrings) { bool isInMultiLine = false; string seriesItem = ""; string stringData = ""; receiveStrings.Clear(); if (!isConnected) return false; while (true) { stringData = ReadLine(); if (null == stringData || 0 == stringData.Length) break; if (0 == receiveStrings.Count) { seriesItem = stringData.Substring(0, 3); try { if ('-' == stringData[3])isInMultiLine = true; } catch (Exception) { ;} } if (0 != receiveStrings.Count && isInMultiLine && '-' != stringData[3] && stringData.Substring(0, 3).Equals(seriesItem)) { receiveStrings.Add(stringData); break; } receiveStrings.Add(stringData); if (!isInMultiLine) break; } if (0 != receiveStrings.Count) return true; return false; } public bool ReceivePage(ArrayList stringArray) { string stringData = ""; int reps = 0; stringArray.Clear(); if (!isConnected) return false; while (true) { stringData = ReadLine(); if (null == stringData || 0 == stringData.Length) reps++; else { stringArray.Add(stringData); reps = 0; } if (2 == reps) break; } return 0 != stringArray.Count ? true : false; } public MemoryStream ReceivePage() { MemoryStream memoryStream; ContentHeader contentHeader; contentHeader = ReadContentHeader(); byte[] bytes = new byte[int.Parse(contentHeader.ContentLength)]; Receive(ref bytes); memoryStream = new MemoryStream(bytes); return memoryStream; } public bool IsInResponse(string responseString, ArrayList responseStrings) { if (0 == responseStrings.Count) return false; for (int index = 0; index < responseStrings.Count; index++) { if (responseString.Equals((string)responseStrings[index])) return true; } return false; } private ContentHeader ReadContentHeader() { ContentHeader contentHeader; String stringLine; String token; String value; contentHeader = new ContentHeader(); while (true) { stringLine = ReadLine(); if (null == stringLine || 0 == stringLine.Length) break; String[] elements = stringLine.Split(':'); if (2 != elements.Length) continue; token = elements[0].Trim().ToUpper(); value = elements[1].Trim().ToUpper(); if ("SERVER".Equals(token)) contentHeader.Server = value; else if ("DATE".Equals(token)) contentHeader.Date = value; else if ("PRAGMA".Equals(token)) contentHeader.Pragma = value; else if ("CACHE-CONTROL".Equals(token)) contentHeader.Cache = value; else if ("CONNECTION".Equals(token)) contentHeader.Connection = value; else if ("CONTENT-LENGTH".Equals(token)) contentHeader.ContentLength = value; else if ("CONTENT-TYPE".Equals(token)) contentHeader.ContentType = value; else if ("SET-COOKIE".Equals(token)) contentHeader.Cookie = value; } return contentHeader; } [Conditional("TRACENET")] public static void TraceOut(String strLine) { String strThread = "[Thread=" + System.Threading.Thread.CurrentThread.GetHashCode() + "]"; String strDate = "[" + DateTime.Now.ToString() + "]"; Trace.WriteLine(strThread + "[]" + strDate + strLine); } } }