public static string GetLocalIPs() { try { StringBuilder Result = new StringBuilder(); IPAddress[] Addresses = Dns.GetHostAddresses(Dns.GetHostName()); foreach (IPAddress Address in Addresses) { if (Result.Length > 0) { Result.Append(","); } Result.Append(Address.ToString()); } return(Result.ToString()); } catch (SocketException sex) { RMLog.DebugException(sex, "SocketException in TcpConnection::GetLocalIPs(). ErrorCode=" + sex.ErrorCode.ToString()); return(""); } catch (Exception ex) { RMLog.DebugException(ex, "Exception in TcpConnection::GetLocalIPs()"); return(""); } }
public void Close() { if (Connected) { try { if (ShutdownOnClose) { _Socket.Shutdown(SocketShutdown.Both); } } catch (SocketException sex) { switch (sex.ErrorCode) { case 10057: break; // The socket is not connected default: RMLog.DebugException(sex, "SocketException in TcpConnection::Close(). ErrorCode=" + sex.ErrorCode.ToString()); break; } } catch (Exception ex) { RMLog.DebugException(ex, "Exception in TcpConnection::Close()"); } if (Connected) { _Stream.Close(); _Socket.Close(); } } InitSocket(); }
public void ReceiveData(int milliseconds) { try { if ((Connected) && (_Socket.Poll(milliseconds * 1000, SelectMode.SelectRead))) { byte[] Buffer = new byte[READ_BUFFER_SIZE]; int BytesRead = _Stream.Read(Buffer, 0, READ_BUFFER_SIZE); if (BytesRead == 0) { // No bytes read means we have a disconnect _Stream.Close(); _Socket.Close(); } else { // If we have bytes, add them to the buffer NegotiateInbound(Buffer, BytesRead); } } } catch (SocketException sex) { RMLog.Exception(sex, "SocketException in TcpConnection::ReceiveData(). ErrorCode=" + sex.ErrorCode.ToString()); } catch (Exception ex) { RMLog.Exception(ex, "Exception in TcpConnection::ReceiveData()"); } }
public bool Listen(string ipAddress, Int32 port) { Close(); try { IPAddress IPA = ParseIPAddress(ipAddress); _Socket = new Socket(IPA.AddressFamily, SocketType.Stream, ProtocolType.Tcp); if (!ProcessUtils.IsRunningOnMono && Socket.OSSupportsIPv6) // From: https://github.com/statianzo/Fleck/blob/master/src/Fleck/WebSocketServer.cs { #if __MonoCS__ #else // Windows default to IPv6Only=true, so we call this to allow connections to both IPv4 and IPv6 // Mono will throw an exception, but that's OK because it defaults to allowing both IPv4 and IPv6 _Socket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, false); // 27 = SocketOptionName.IPv6Only #endif } _Socket.Blocking = true; _Socket.Bind(new IPEndPoint(IPA, port)); _Socket.Listen(5); return(true); } catch (SocketException sex) { RMLog.DebugException(sex, "SocketException in TcpConnection::Listen(). ErrorCode=" + sex.ErrorCode.ToString()); return(false); } catch (Exception ex) { RMLog.DebugException(ex, "Exception in TcpConnection::Listen()"); return(false); } }
public bool Open(byte[] socketInformationBytes) { try { SocketInformation SI = new SocketInformation() { ProtocolInformation = socketInformationBytes, Options = SocketInformationOptions.Connected, }; _Socket = new Socket(SI) { Blocking = true, }; if (_Socket.Connected) { _Stream = new NetworkStream(_Socket); } return(_Socket.Connected); } catch (SocketException sex) { RMLog.DebugException(sex, "SocketException in TcpConnection::Open(). ErrorCode=" + sex.ErrorCode.ToString()); return(false); } catch (Exception ex) { RMLog.DebugException(ex, "Exception in TcpConnection::Open()"); return(false); } }
public bool Listen(string ipAddress, Int32 port) { Close(); try { IPEndPoint LocalEP; if ((string.IsNullOrEmpty(ipAddress)) || (ipAddress == "0.0.0.0")) { LocalEP = new IPEndPoint(IPAddress.Any, port); } else { LocalEP = new IPEndPoint(IPAddress.Parse(ipAddress), port); } _Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _Socket.Blocking = true; _Socket.Bind(LocalEP); _Socket.Listen(5); return(true); } catch (SocketException sex) { RMLog.Exception(sex, "SocketException in TcpConnection::Listen(). ErrorCode=" + sex.ErrorCode.ToString()); return(false); } catch (Exception ex) { RMLog.Exception(ex, "Exception in TcpConnection::Listen()"); return(false); } }
public virtual bool Open(Socket socket) { Close(); try { _Socket = socket; _Socket.Blocking = true; if (_Socket.Connected) { _LocalIP = ((IPEndPoint)_Socket.LocalEndPoint).Address.ToString(); _LocalPort = ((IPEndPoint)_Socket.LocalEndPoint).Port; _RemoteIP = ((IPEndPoint)_Socket.RemoteEndPoint).Address.ToString(); _RemotePort = ((IPEndPoint)_Socket.RemoteEndPoint).Port; _Stream = new NetworkStream(_Socket); } return(_Socket.Connected); } catch (SocketException sex) { RMLog.Exception(sex, "SocketException in TcpConnection::Open(). ErrorCode=" + sex.ErrorCode.ToString()); return(false); } catch (Exception ex) { RMLog.Exception(ex, "Exception in TcpConnection::Open()"); return(false); } }
public bool Connect(string hostName, Int32 port) { Close(); try { _Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _Socket.Blocking = true; _Socket.Connect(hostName, port); if (_Socket.Connected) { _LocalIP = ((IPEndPoint)_Socket.LocalEndPoint).Address.ToString(); _LocalPort = ((IPEndPoint)_Socket.LocalEndPoint).Port; _RemoteIP = ((IPEndPoint)_Socket.RemoteEndPoint).Address.ToString(); _RemotePort = ((IPEndPoint)_Socket.RemoteEndPoint).Port; _Stream = new NetworkStream(_Socket); } return(_Socket.Connected); } catch (SocketException sex) { RMLog.Exception(sex, "SocketException in TcpConnection::Connect(). ErrorCode=" + sex.ErrorCode.ToString()); return(false); } catch (Exception ex) { RMLog.Exception(ex, "Exception in TcpConnection::Connect()"); return(false); } }
public void Close() { if (Connected) { try { if (ShutdownOnClose) { _Socket.Shutdown(SocketShutdown.Both); } } catch (SocketException sex) { RMLog.Exception(sex, "SocketException in TcpConnection::Close(). ErrorCode=" + sex.ErrorCode.ToString()); } catch (Exception ex) { RMLog.Exception(ex, "Exception in TcpConnection::Close()"); } if (Connected) { _Stream.Close(); _Socket.Close(); } } InitSocket(); }
private bool ShakeHandsHixie76() { // Ensure we have all the data we need if ((_Header.ContainsKey("Key1")) && (_Header.ContainsKey("Key2")) && (_Header.ContainsKey("Host")) && (_Header.ContainsKey("Origin")) && (_Header.ContainsKey("Path"))) { List <byte> ToHash = new List <byte>(); byte[] TempBytes; // Get the data to hash TempBytes = BitConverter.GetBytes(CalculateWebSocketKey(_Header["Key1"])); for (int i = 3; i >= 0; i--) { ToHash.Add(TempBytes[i]); } TempBytes = BitConverter.GetBytes(CalculateWebSocketKey(_Header["Key2"])); for (int i = 3; i >= 0; i--) { ToHash.Add(TempBytes[i]); } ToHash.AddRange(ReadBytes(8)); // Hash the data byte[] Hashed = MD5.Create().ComputeHash(ToHash.ToArray()); // Setup the handshake response string Response = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" + "Upgrade: WebSocket\r\n" + "Connection: Upgrade\r\n" + "Sec-WebSocket-Origin: " + _Header["Origin"] + "\r\n" + "Sec-WebSocket-Location: ws://" + _Header["Host"] + _Header["Path"] + "\r\n"; if (_Header.ContainsKey("SubProtocol")) { Response += "Sec-WebSocket-Protocol: plain\r\n"; // Only sub-protocol we support } Response += "\r\n"; // Send the response and return WriteBytes(Encoding.ASCII.GetBytes(Response)); WriteBytes(Hashed); return(true); } else { // We're missing some pice of data, log what we do have RMLog.Error("Missing some piece of handshake data. Here's what we have:"); foreach (DictionaryEntry DE in _Header) { RMLog.Error(DE.Key + " => " + DE.Value); } return(false); } }
public static string GetIPByName(string hostName) { try { return(Dns.GetHostEntry(hostName).AddressList[0].ToString()); } catch (SocketException sex) { RMLog.DebugException(sex, "SocketException in TcpConnection::GetIPByName(). ErrorCode=" + sex.ErrorCode.ToString()); return(""); } catch (Exception ex) { RMLog.DebugException(ex, "Exception in TcpConnection::GetIPByName()"); return(""); } }
public Socket Accept() { try { return(_Socket.Accept()); } catch (SocketException sex) { RMLog.DebugException(sex, "SocketException in TcpConnection::Accept(). ErrorCode=" + sex.ErrorCode.ToString()); return(null); } catch (Exception ex) { RMLog.DebugException(ex, "Exception in TcpConnection::Accept()"); return(null); } }
public static string GetHostByIP(string ipAddress) { try { return(Dns.GetHostEntry(ipAddress).HostName.ToString()); } catch (SocketException sex) { RMLog.DebugException(sex, "SocketException in TcpConnection::GetHostByIP(). ErrorCode=" + sex.ErrorCode.ToString()); return(""); } catch (Exception ex) { RMLog.DebugException(ex, "Exception in TcpConnection::GetHostByIP()"); return(""); } }
public bool CanAccept(int milliseconds) { try { return((_Socket == null) ? false : _Socket.Poll(milliseconds * 1000, SelectMode.SelectRead)); } catch (SocketException sex) { RMLog.DebugException(sex, "SocketException in TcpConnection::CanAccept(). ErrorCode=" + sex.ErrorCode.ToString()); return(false); } catch (Exception ex) { RMLog.DebugException(ex, "Exception in TcpConnection::CanAccept()"); return(false); } }
private bool ShakeHandsRFC6455() { // Ensure we have all the data we need // TODOX Firefox (v49, maybe others) is not sending an Origin header, which breaks things // TODOX if ((_Header.ContainsKey("Key")) && (_Header.ContainsKey("Host")) && (_Header.ContainsKey("Origin")) && (_Header.ContainsKey("Path"))) if ((_Header.ContainsKey("Key")) && (_Header.ContainsKey("Host")) && (_Header.ContainsKey("Path"))) { string AcceptGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; // Combine Key and GUID string ToHash = _Header["Key"] + AcceptGUID; // Hash the string byte[] Hashed = SHA1.Create().ComputeHash(Encoding.ASCII.GetBytes(ToHash)); // Encode the hash string Encoded = Convert.ToBase64String(Hashed); // Setup the handshake response var Response = "HTTP/1.1 101 Switching Protocols\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n" + "Sec-WebSocket-Accept: " + Encoded + "\r\n"; if (_Header.ContainsKey("SubProtocol")) { Response += "Sec-WebSocket-Protocol: plain\r\n"; // Only sub-protocol we support } Response += "\r\n"; // Send the response and return WriteBytes(Encoding.ASCII.GetBytes(Response)); return(true); } else { // We're missing some pice of data, log what we do have RMLog.Debug("Missing some piece of handshake data. Here's what we have:"); foreach (DictionaryEntry DE in _Header) { RMLog.Debug(DE.Key + " => " + DE.Value); } return(false); } }
public static IPAddress GetAddrByName(string hostName) { try { IPAddress[] Addresses = Dns.GetHostAddresses(hostName); return((Addresses.Length > 0) ? Addresses[0] : IPAddress.None); } catch (SocketException sex) { RMLog.DebugException(sex, "SocketException in TcpConnection::GetAddrByName(). ErrorCode=" + sex.ErrorCode.ToString()); return(IPAddress.None); } catch (Exception ex) { RMLog.DebugException(ex, "Exception in TcpConnection::GetAddrByName()"); return(IPAddress.None); } }
public void WriteRaw(byte[] data) { if (Connected) { try { // TODO Will this always write all the bytes? _Stream.Write(data, 0, data.Length); } catch (IOException ioex) { if (ioex.Message == "Write failure") { // Apparently we have a disconnect } else { RMLog.DebugException(ioex, "IOException in TcpConnection::WriteRaw()"); } _Stream.Close(); _Socket.Close(); } catch (SocketException sex) { if ((sex.Message == "An established connection was aborted by the software in your host machine") || (sex.Message == "An existing connection was forcibly closed by the remote host")) { // Apparently we have a disconnect } else { RMLog.DebugException(sex, "SocketException in TcpConnection::WriteRaw(). ErrorCode=" + sex.ErrorCode.ToString()); } _Stream.Close(); _Socket.Close(); } catch (Exception ex) { RMLog.DebugException(ex, "Exception in TcpConnection::ReceiveData()"); _Stream.Close(); _Socket.Close(); } } }
public TcpConnection AcceptTCP() { try { Socket NewSocket = _Socket.Accept(); TcpConnection NewConnection = new TcpConnection(); NewConnection.Open(NewSocket); return(NewConnection); } catch (SocketException sex) { RMLog.DebugException(sex, "SocketException in TcpConnection::AcceptTCP(). ErrorCode=" + sex.ErrorCode.ToString()); return(null); } catch (Exception ex) { RMLog.DebugException(ex, "Exception in TcpConnection::AcceptTCP()"); return(null); } }
public virtual bool Open(Socket socket) { Close(); try { _Socket = socket; _Socket.Blocking = true; if (_Socket.Connected) { _LocalIP = ((IPEndPoint)_Socket.LocalEndPoint).Address.ToString(); _LocalPort = ((IPEndPoint)_Socket.LocalEndPoint).Port; _RemoteIP = ((IPEndPoint)_Socket.RemoteEndPoint).Address.ToString(); _RemotePort = ((IPEndPoint)_Socket.RemoteEndPoint).Port; _Stream = new NetworkStream(_Socket); if (_RemoteIP.ToLower().StartsWith("::ffff:")) { _RemoteIP = _RemoteIP.Substring(7); // Trim leading ::ffff: } else if (((IPEndPoint)_Socket.RemoteEndPoint).Address.AddressFamily == AddressFamily.InterNetworkV6) { _RemoteIP = "[" + _RemoteIP + "]"; // Wrap IPv6 in [] } } return(_Socket.Connected); } catch (SocketException sex) { RMLog.DebugException(sex, "SocketException in TcpConnection::Open(). ErrorCode=" + sex.ErrorCode.ToString()); return(false); } catch (Exception ex) { RMLog.DebugException(ex, "Exception in TcpConnection::Open()"); return(false); } }
public bool Open(int ASocketHandle) { if (OSUtils.IsWindows) { try { NativeMethods.WSAData WSA = new NativeMethods.WSAData(); SocketError Result = NativeMethods.WSAStartup((short)0x0202, out WSA); if (Result != SocketError.Success) { throw new SocketException(NativeMethods.WSAGetLastError()); } SocketPermission SP = new SocketPermission(System.Security.Permissions.PermissionState.Unrestricted); SP.Demand(); SocketInformation SI = new SocketInformation() { Options = SocketInformationOptions.Connected, ProtocolInformation = new byte[Marshal.SizeOf(typeof(NativeMethods.WSAPROTOCOL_INFO))], }; Result = SocketError.Success; unsafe { fixed(byte *pinnedBuffer = SI.ProtocolInformation) { Result = NativeMethods.WSADuplicateSocket(new IntPtr(ASocketHandle), (uint)Process.GetCurrentProcess().Id, pinnedBuffer); } } if (Result != SocketError.Success) { throw new SocketException(NativeMethods.WSAGetLastError()); } return(Open(new Socket(SI))); } catch (SocketException sex) { RMLog.DebugException(sex, "SocketException in TcpConnection::Open(). ErrorCode=" + sex.ErrorCode.ToString()); return(false); } catch (Exception ex) { RMLog.DebugException(ex, "Exception in TcpConnection::Open()"); return(false); } } else { RMLog.Debug("MONO cannot open an existing socket handle"); return(false); //try //{ // SocketInformation SI = new SocketInformation(); // SI.Options = SocketInformationOptions.Connected; // SI.ProtocolInformation = new byte[24]; // // From Mono's Socket.cs DuplicateAndClose() SI.ProtocolInformation = Mono.DataConverter.Pack("iiiil", (int)address_family, (int)socket_type, (int)protocol_type, isbound ? 1 : 0, (long)socket); // byte[] B1 = BitConverter.GetBytes((int)AddressFamily.InterNetwork); // byte[] B2 = BitConverter.GetBytes((int)SocketType.Stream); // byte[] B3 = BitConverter.GetBytes((int)ProtocolType.Tcp); // byte[] B4 = BitConverter.GetBytes((int)1); // byte[] B5 = BitConverter.GetBytes((long)ASocketHandle); // Array.Copy(B1, 0, SI.ProtocolInformation, 0, B1.Length); // Array.Copy(B2, 0, SI.ProtocolInformation, 4, B2.Length); // Array.Copy(B3, 0, SI.ProtocolInformation, 8, B3.Length); // Array.Copy(B4, 0, SI.ProtocolInformation, 12, B4.Length); // Array.Copy(B5, 0, SI.ProtocolInformation, 16, B5.Length); // return Open(new Socket(SI)); //} //catch (SocketException sex) //{ // RMLog.DebugException(sex, "SocketException in TcpConnection::Open(). ErrorCode=" + sex.ErrorCode.ToString()); // return false; //} //catch (Exception ex) //{ // RMLog.DebugException(ex, "Exception in TcpConnection::Open()"); // return false; //} } }
private bool ShakeHands() { _Header["Version"] = "0"; try { // Peek first byte for 22, 128 (indicates ssl) // Don't use class methods for peek/read since they eat data into the input buffer, and AuthenticateAsServer needs that data if (_Socket.Poll(5 * 1000 * 1000, SelectMode.SelectRead)) { byte[] FirstByte = new byte[1]; _Socket.Receive(FirstByte, 0, 1, SocketFlags.Peek); if ((FirstByte[0] == 22) || (FirstByte[0] == 128)) { if (_Certificate == null) { throw new Exception("wss:// requires a certificate"); } else { var SSL = new SslStream(_Stream, false); _Stream = SSL; SSL.AuthenticateAsServer(_Certificate, false, SslProtocols.Tls, false); Protocol = "wss"; } } } else { RMLog.Error("Timeout exceeded while waiting for complete handshake"); return(false); } // Keep reading header data until we get all the data we want while (true) { // Read another line, and abort if we don't get one within 5 seconds string InLine = ReadLn(new string[] { "\r\n", "\0" }, false, '\0', 5000).Trim(); if (ReadTimedOut) { RMLog.Error("Timeout exceeded while waiting for complete handshake"); return(false); } RMLog.Trace("Handshake Line: " + InLine); // Check for blank line (indicates we have most of the header, and only the last 8 bytes remain if (string.IsNullOrEmpty(InLine)) { switch (_Header["Version"]) { case "0": if (_Header.ContainsKey("Sec-WebSocket-Key1")) { _ProtocolVersion = ProtocolVersion.Hixie76; return(ShakeHandsHixie76()); } else { // Only used by Chrome 4 and iOS 5.0.0 so probably not worth bothering _ProtocolVersion = ProtocolVersion.Hixie75; return(false); } case "7": case "8": case "13": _ProtocolVersion = ProtocolVersion.RFC6455; return(ShakeHandsRFC6455()); default: // TODO If this version does not // match a version understood by the server, the server MUST // abort the websocket handshake described in this section and // instead send an appropriate HTTP error code (such as 426 // Upgrade Required), and a |Sec-WebSocket-Version| header // indicating the version(s) the server is capable of // understanding. return(false); } break; } else if (InLine.StartsWith("Connection:")) { // Example: "Connection: Upgrade" // NB: New in protocol 8+ _Header["Connection"] = InLine.Replace("Connection:", "").Trim(); } else if (InLine.StartsWith("GET")) { // Example: "GET /demo HTTP/1.1" string[] GET = InLine.Split(' '); _Header["Path"] = GET[1]; } else if (InLine.StartsWith("Host:")) { // Example: "Host: example.com" _Header["Host"] = InLine.Replace("Host:", "").Trim(); } else if (InLine.StartsWith("Origin:")) { // Example: "Origin: http://example.com" // NB: Not used in protocol 8+ _Header["Origin"] = InLine.Replace("Origin:", "").Trim(); } else if (InLine.StartsWith("Sec-WebSocket-Key:")) { // Example: "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" // NB: New in protocol 8+ _Header["Key"] = InLine.Replace("Sec-WebSocket-Key:", "").Trim(); } else if (InLine.StartsWith("Sec-WebSocket-Key1:")) { // Example: "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5" // NB: Not used in protocol 8+ _Header["Key1"] = InLine.Replace("Sec-WebSocket-Key1:", "").Trim(); } else if (InLine.StartsWith("Sec-WebSocket-Key2:")) { // Example: "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00" // NB: Not used in protocol 8+ _Header["Key2"] = InLine.Replace("Sec-WebSocket-Key2:", "").Trim(); } else if (InLine.StartsWith("Sec-WebSocket-Origin:")) { // Example: "Sec-WebSocket-Origin: http://example.com" // NB: New in protocol 8+ _Header["Origin"] = InLine.Replace("Sec-WebSocket-Origin:", "").Trim(); } else if (InLine.StartsWith("Sec-WebSocket-Protocol:")) { // Example: "Sec-WebSocket-Protocol: sample" _Header["SubProtocol"] = InLine.Replace("Sec-WebSocket-Protocol:", "").Trim(); } else if (InLine.StartsWith("Sec-WebSocket-Draft")) { // Example: "Sec-WebSocket-Draft: 2" _Header["Version"] = InLine.Replace("Sec-WebSocket-Draft:", "").Trim(); } else if (InLine.StartsWith("Sec-WebSocket-Version")) { // Example: "Sec-WebSocket-Version: 8" _Header["Version"] = InLine.Replace("Sec-WebSocket-Version:", "").Trim(); } else if (InLine.StartsWith("Upgrade:")) { // Example: "Upgrade: websocket" // NB: New in protocol 8+ _Header["Upgrade"] = InLine.Replace("Upgrade:", "").Trim(); } else if (InLine.StartsWith("<policy-file-request")) { string PolicyResponse = "<?xml version=\"1.0\"?>\n" + "<cross-domain-policy>\n" + " <allow-access-from domain=\"*\" to-ports=\"*\"/>\n" + " <site-control permitted-cross-domain-policies=\"all\"/>\n" + "</cross-domain-policy>\n" + "\0"; WriteRaw(Encoding.UTF8.GetBytes(PolicyResponse)); FlashPolicyFileRequest = true; return(false); } } } catch (Exception ex) { RMLog.Exception(ex, "Exception in WebSocketConnection::ShakeHands()"); } return(false); }
public bool Connect(string hostName, Int32 port) { Close(); try { // Get the ip addresses for the give hostname, and then convert from ipv4 to ipv6 if necessary var HostAddresses = new List <IPAddress>(); if (!Socket.OSSupportsIPv6) { HostAddresses.AddRange(Dns.GetHostAddresses(hostName)); _Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); } else { foreach (var IPA in Dns.GetHostAddresses(hostName)) { if (IPA.AddressFamily == AddressFamily.InterNetwork) { HostAddresses.Add(IPAddress.Parse("::ffff:" + IPA.ToString())); } else { HostAddresses.Add(IPA); } } _Socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); // Only do the Mono check here because the XP check is done above if (!ProcessUtils.IsRunningOnMono) // From: https://github.com/statianzo/Fleck/blob/master/src/Fleck/WebSocketServer.cs { #if __MonoCS__ #else // Windows default to IPv6Only=true, so we call this to allow connections to both IPv4 and IPv6 // Mono will throw an exception, but that's OK because it defaults to allowing both IPv4 and IPv6 _Socket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, false); // 27 = SocketOptionName.IPv6Only #endif } } _Socket.Blocking = true; _Socket.Connect(HostAddresses.ToArray(), port); if (_Socket.Connected) { _LocalIP = ((IPEndPoint)_Socket.LocalEndPoint).Address.ToString(); _LocalPort = ((IPEndPoint)_Socket.LocalEndPoint).Port; _RemoteIP = ((IPEndPoint)_Socket.RemoteEndPoint).Address.ToString(); _RemotePort = ((IPEndPoint)_Socket.RemoteEndPoint).Port; _Stream = new NetworkStream(_Socket); if (_RemoteIP.ToLower().StartsWith("::ffff:")) { _RemoteIP = _RemoteIP.Substring(7); // Trim leading ::ffff: } else if (((IPEndPoint)_Socket.RemoteEndPoint).Address.AddressFamily == AddressFamily.InterNetworkV6) { _RemoteIP = "[" + _RemoteIP + "]"; // Wrap IPv6 in [] } } return(_Socket.Connected); } catch (SocketException sex) { switch (sex.ErrorCode) { case 10060: break; // Connection timed out case 10061: break; // Connection refused case 10065: break; // No route to host default: RMLog.DebugException(sex, "SocketException in TcpConnection::Connect(). ErrorCode=" + sex.ErrorCode.ToString()); break; } return(false); } catch (Exception ex) { RMLog.DebugException(ex, "Exception in TcpConnection::Connect()"); return(false); } }