/// <summary> /// Places the <see cref="WinSocket"/> into a listening state. /// </summary> /// <param name="ipAddress">An <see cref="IPAddress"/> containing the IP address to start listening on. Null to listen on all available interfaces.</param> /// <param name="port">The port to start listening on.</param> /// <remarks>Threading hasn't really started yet, so allow exceptions to bubble-up.</remarks> public void Listen(IPAddress ipAddress, int port) { bool ipWasNull = (ipAddress == null); if (ipWasNull) { ipAddress = Socket.OSSupportsIPv6 ? IPAddress.IPv6Any : IPAddress.Any; } AddressFamily family = ipAddress.AddressFamily; SocketType stype = (Parent.Protocol == Protocol.Tcp) ? SocketType.Stream : SocketType.Dgram; ProtocolType ptype = (Parent.Protocol == Protocol.Tcp) ? ProtocolType.Tcp : ProtocolType.Udp; int portUsed = port; socket = new AsyncSocket(family, stype, ptype); if (ipWasNull && ipAddress == IPAddress.IPv6Any) { socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, 0); } if (ptype == ProtocolType.Udp) { socket.SetSocketOption((family == AddressFamily.InterNetworkV6 ? SocketOptionLevel.IPv6 : SocketOptionLevel.IP), SocketOptionName.PacketInformation, true); } var localEndpoint = new IPEndPoint(ipAddress, port); socket.Bind(localEndpoint); if (port == 0) { portUsed = ((IPEndPoint)socket.LocalEndPoint).Port; Parent.ChangeLocalPort(portUsed); } if (Parent.Protocol == Protocol.Tcp) { (new Thread(ListenTCP)).Start(); } else // UPD { (new Thread(ListenUDP)).Start(); } }
/// <summary> /// Establishes a connection to a remote host. /// </summary> /// <param name="remoteHostOrIp">A value containing the Hostname or IP address of the remote host.</param> /// <param name="remotePort">A value indicating the port on the remote host to connect to.</param> /// <param name="sslHost">The name of the host to validate the certificate for.</param> /// <param name="localIp">A value indicating the IP address the client should connect from.</param> /// <param name="localPort">A value indicating the port the client should connect from.</param> public async void Connect(string remoteHostOrIp, int remotePort, string sslHost, string localIp, int localPort) { if (Parent.State != State.Closed) { throw new WinsockException("Cannot connect to a remote host when not Closed."); } /** * First we need to make sure we have an IP address. * If not - we need to try and resolve the fully qualified domain. */ Parent.ChangeState(State.ResolvingHost); IPAddress resolvedRemoteIP = null, resolvedLocalIP = null; if (!IPAddress.TryParse(remoteHostOrIp, out resolvedRemoteIP)) { IPHostEntry entry = await Dns.GetHostEntryAsync(remoteHostOrIp); if (entry == null || entry.AddressList.Length == 0) { string name = (entry != null) ? entry.HostName : remoteHostOrIp; throw new WinsockException(string.Format("Hostname \"{0}\" could not be resolved.", name)); } resolvedRemoteIP = entry.AddressList[0]; } if (!string.IsNullOrWhiteSpace(localIp) && !IPAddress.TryParse(localIp, out resolvedLocalIP)) { throw new WinsockException(string.Format("The value \"{0}\" is not a valid IP address for local binding.", localIp)); } Parent.ChangeState(State.HostResolved); /** * Take our IP address and attempt to create the connection. * Upon successfull connections - different BeginReceives could be called * depending on if this was an attempt at a SECURE connection. */ IPEndPoint endPoint = new IPEndPoint(resolvedRemoteIP, remotePort); IPEndPoint localEndPoint = (resolvedLocalIP != null) ? new IPEndPoint(resolvedLocalIP, localPort) : null; socket = new AsyncSocket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); Parent.ChangeState(State.Connecting); bool connectFail = false; try { if (localEndPoint != null) { socket.Bind(localEndPoint); } await socket.ConnectAsync(endPoint); } catch (Exception ex) { connectFail = true; Parent.ChangeState(State.Closed); Parent.OnErrorReceived(Parent, ErrorReceivedEventArgs.Create(ex)); } if (!connectFail) { Parent.ChangeState(State.Connected); Parent.OnConnected(endPoint); if (sslHost != null) { BeginReceive(false, sslHost); } else { BeginReceive(false); } } }
/// <summary> /// Places the <see cref="WinSocket"/> into a listening state. /// </summary> /// <param name="ipAddress">An <see cref="IPAddress"/> containing the IP address to start listening on. Null to listen on all available interfaces.</param> /// <param name="port">The port to start listening on.</param> /// <remarks>Threading hasn't really started yet, so allow exceptions to bubble-up.</remarks> public void Listen(IPAddress ipAddress, int port) { bool ipWasNull = (ipAddress == null); if (ipWasNull) ipAddress = Socket.OSSupportsIPv6 ? IPAddress.IPv6Any : IPAddress.Any; AddressFamily family = ipAddress.AddressFamily; SocketType stype = (Parent.Protocol == Protocol.Tcp) ? SocketType.Stream : SocketType.Dgram; ProtocolType ptype = (Parent.Protocol == Protocol.Tcp) ? ProtocolType.Tcp : ProtocolType.Udp; int portUsed = port; socket = new AsyncSocket(family, stype, ptype); if (ipWasNull && ipAddress == IPAddress.IPv6Any) socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, 0); if (ptype == ProtocolType.Udp) socket.SetSocketOption((family == AddressFamily.InterNetworkV6 ? SocketOptionLevel.IPv6 : SocketOptionLevel.IP), SocketOptionName.PacketInformation, true); var localEndpoint = new IPEndPoint(ipAddress, port); socket.Bind(localEndpoint); if (port == 0) { portUsed = ((IPEndPoint)socket.LocalEndPoint).Port; Parent.ChangeLocalPort(portUsed); } if (Parent.Protocol == Protocol.Tcp) (new Thread(ListenTCP)).Start(); else // UPD (new Thread(ListenUDP)).Start(); }