/// <inheritdoc /> public void Bind(IPAddress localAddress) { IPEndPoint ep; _serverSocket = Socket2.CreateSocketAndBindToAnyPort(localAddress, out ep); _localEndPoint = ep; Listen(); }
public void TestCreateSocketAndBindToAnyPort3() { IPEndPoint address; using (var socket = Socket2.CreateSocketAndBindToAnyPort(IPAddress.Any, out address)) { socket.ExclusiveAddressUse.Should().BeTrue(); } }
private static void UnInitModules() { Socket1?.DestroySocketTask(); Socket2?.DestroySocketTask(); var route = new BaseNetUtil[8] { User, Room, Sender, Matcher, FrameSender.NetUtil1, FrameSender.NetUtil2, Pinger1, Pinger2 }; foreach (var request in route) { request?.UnbindSocket(); } }
public void TestCreateSocketAndBindToAnyPort2() { using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { const ushort usedPort = 55555; socket.Bind(new IPEndPoint(IPAddress.Loopback, usedPort)); IPEndPoint address; new Action(() => Socket2.CreateSocketAndBindToAnyPort(IPAddress.Any, usedPort, usedPort, out address) ) .Should().Throw <SystemException>() .WithMessage("No more available sockets"); } }
/// <summary> /// Binds this socket to the given address. /// The listening port will in the range of [<paramref name="minPort"/>, <paramref name="maxPort"/>] and can be retrieved /// via <see cref="LocalEndPoint"/> after this call has succeeded. /// </summary> /// <remarks> /// The current implementation tries to bind the socket to <paramref name="minPort"/> and then increments /// it by one until either a Bind() operation succeeds or maxPort has been reached. If the latter occured /// (and Bind() still didn't succeed, then a <see cref="SystemException"/> is thrown. /// </remarks> /// <param name="localAddress"></param> /// <param name="minPort">The minimum port number to which this endpoint may be bound to</param> /// <param name="maxPort">The maximum port number to which this endpoint may be bound to</param> /// <exception cref="SystemException">When none of the given ports is available</exception> public void Bind(IPAddress localAddress, ushort minPort, ushort maxPort) { if (localAddress == null) { throw new ArgumentNullException(nameof(localAddress)); } if (IsConnected) { throw new InvalidOperationException("A socket may only bound to a particular port when its not already connected"); } IPEndPoint ep; _serverSocket = Socket2.CreateSocketAndBindToAnyPort(localAddress, minPort, maxPort, out ep); LocalEndPoint = ep; Listen(); }
/// <summary> /// Binds this socket /// </summary> /// <param name="ep"></param> public void Bind(IPEndPoint ep) { if (ep == null) { throw new ArgumentNullException(nameof(ep)); } var socket = new Socket2(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp) { ExclusiveAddressUse = true }; socket.Bind(ep); _serverSocket = socket; LocalEndPoint = ep; Listen(); }
private static void ListenSocketConnect() { // 联网 Socket1.OnEvent("connect", (SocketEvent socketEvent) => { // 联网时自动Login if (!UserStatus.IsStatus(UserStatus.StatusType.Logining)) { UserUtil.Login(null); } if (string.IsNullOrEmpty(Socket1.Url)) { return; } var eve = new ResponseEvent(ErrCode.EcOk) { Data = Socket1.Id }; Sdk.Responses.OnNetwork(eve); }); Socket2.OnEvent("connect", (SocketEvent socketEvent) => { // check login 成功后发送业务数据 FrameSender.CheckLogin(null, "connect " + !!Socket2.IsSocketStatus("connect")); if (!string.IsNullOrEmpty(Socket2.Url)) { var eve = new ResponseEvent(ErrCode.EcOk) { Data = Socket2.Id }; Sdk.Responses.OnNetwork(eve); } Pinger2.Ping(null); }); // 断网 Socket1.OnEvent("connectClose", (SocketEvent socketEvent) => { // 初始化失败 SdkInitCallback(false, new ResponseEvent(ErrCode.EcSdkSocketClose)); if (!SdkStatus.IsInited()) { return; } // 断网时自动 Logout UserStatus.SetStatus(UserStatus.StatusType.Logout); if (string.IsNullOrEmpty(Socket1.Url)) { return; } var eve = new ResponseEvent(ErrCode.EcSdkSocketClose, "Socket 断开", null, null); Sdk.Responses.OnNetwork(eve); }); Socket2.OnEvent("connectClose", (SocketEvent socketEvent) => { if (!SdkStatus.IsInited()) { return; } Debugger.Log("socket2 on connect close"); CheckLoginStatus.SetStatus(CheckLoginStatus.StatusType.Offline); if (!string.IsNullOrEmpty(Socket2.Url)) { var eve = new ResponseEvent(ErrCode.EcSdkSocketClose, "Socket 断开", null, null); Sdk.Responses.OnNetwork(eve); } ; Pinger2.Stop(); }); // socket 错误 Socket1.OnEvent("connectError", (SocketEvent socketEvent) => { // 初始化失败 SdkInitCallback(false, new ResponseEvent(ErrCode.EcSdkSocketError)); if (!SdkStatus.IsInited()) { return; } if (string.IsNullOrEmpty(Socket1.Url)) { return; } var eve = new ResponseEvent(ErrCode.EcSdkSocketError, "Socket 错误", null, null); Sdk.Responses.OnNetwork(eve); }); Socket2.OnEvent("connectError", (SocketEvent socketEvent) => { if (!SdkStatus.IsInited()) { return; } if (string.IsNullOrEmpty(Socket2.Url)) { return; } var eve = new ResponseEvent(ErrCode.EcSdkSocketError, "Socket 错误", null, null); Sdk.Responses.OnNetwork(eve); }); // 需要自动登录 Socket1.OnEvent("autoAuth", (SocketEvent socketEvent) => { if (!SdkStatus.IsInited()) { return; } var timer = new Timer(); timer.SetTimeout(() => { var isLogout = UserStatus.IsStatus(UserStatus.StatusType.Logout); if (!string.IsNullOrEmpty(Socket1.Url) && isLogout) { UserUtil.Login(null); } ; }, 1000); }); Socket2.OnEvent("autoAuth", (SocketEvent socketEvent) => { if (!SdkStatus.IsInited()) { return; } if (string.IsNullOrEmpty(Socket2.Url)) { return; } var timer = new Timer(); timer.SetTimeout(() => { // Debugger.Log("auto auth check 1"); // 检查是否需要重登录 if (UserStatus.IsStatus(UserStatus.StatusType.Logout)) { UserUtil.Login(null); } // 检查是否需要 checkLogin var info = FrameSender.RoomInfo ?? new RoomInfo { RouteId = "" }; // Debugger.Log("auto auth check 2: {0}", CheckLoginStatus.GetRouteId() != info.RouteId); if (CheckLoginStatus.IsOffline() || CheckLoginStatus.GetRouteId() != info.RouteId) { FrameSender.CheckLogin((ResponseEvent eve) => { if (eve.Code == ErrCode.EcOk) { Pinger2.Ping(null); } }, "autoAuth"); } }, 1000); }); }
/// <summary> /// Tries to connect this endPoint to the given one. /// </summary> /// <param name="endPoint"></param> /// <param name="timeout"> /// The amount of time this method should block and await a successful connection from the remote /// end-point /// </param> /// <param name="connectionId"></param> /// <param name="exception"></param> /// <exception cref="ArgumentNullException"> /// When <paramref name="endPoint" /> is null /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// When <paramref name="timeout" /> is equal or less than <see cref="TimeSpan.Zero" /> /// </exception> /// <exception cref="InvalidOperationException"> /// When this endPoint is already connected to another endPoint. /// </exception> public bool TryConnect(IPEndPoint endPoint, TimeSpan timeout, out Exception exception, out ConnectionId connectionId) { if (endPoint == null) { throw new ArgumentNullException(nameof(endPoint)); } if (Equals(endPoint, LocalEndPoint)) { throw new ArgumentException("An endPoint cannot be connected to itself", nameof(endPoint)); } if (timeout <= TimeSpan.Zero) { throw new ArgumentOutOfRangeException(nameof(timeout)); } if (IsConnected) { throw new InvalidOperationException( "This endPoint is already connected to another endPoint and cannot establish any more connections"); } Log.DebugFormat("{0}: Trying to connect to '{1}', timeout: {2}ms", Name, endPoint, timeout.TotalMilliseconds); var success = false; ISocket socket = null; try { var started = DateTime.Now; var task = new Task <Exception>(() => { try { Log.DebugFormat("Task to connect to '{0}' started", endPoint); socket = new Socket2(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp) { ExclusiveAddressUse = true, Blocking = true }; Log.DebugFormat("{0}: EndPoint connecting to remote endpoint '{1}'", Name, endPoint); socket.Connect(endPoint); Log.DebugFormat("{0}: EndPoint successfully connected to remote endpoint '{1}'", Name, endPoint); return(null); } catch (SocketException e) { return(e); } catch (Exception e) { Log.WarnFormat("{0}: Caught unexpected exception while trying to connect to socket: {1}", Name, e); return(e); } }, TaskCreationOptions.LongRunning); task.Start(); if (!task.Wait(timeout)) { exception = new NoSuchIPEndPointException(endPoint, timeout); CurrentConnectionId = connectionId = ConnectionId.None; return(false); } if (task.Result != null) { exception = new NoSuchIPEndPointException(endPoint, task.Result); CurrentConnectionId = connectionId = ConnectionId.None; return(false); } var remaining = timeout - (DateTime.Now - started); ErrorType errorType; string error; object errorReason; if (!TryPerformOutgoingHandshake(socket, remaining, out errorType, out error, out connectionId, out errorReason)) { switch (errorType) { case ErrorType.Handshake: exception = new HandshakeException(error); break; case ErrorType.AuthenticationRequired: exception = new AuthenticationRequiredException(error); break; case ErrorType.EndPointBlocked: exception = new RemoteEndpointAlreadyConnectedException(error, errorReason as IPEndPoint); break; default: exception = new AuthenticationException(error); break; } CurrentConnectionId = connectionId; return(false); } RemoteEndPoint = endPoint; LocalEndPoint = (IPEndPoint)socket.LocalEndPoint; Log.InfoFormat("{0}: EndPoint successfully connected to '{1}'", Name, endPoint); FireOnConnected(endPoint, CurrentConnectionId); success = true; exception = null; return(true); } finally { if (!success) { if (socket != null) { socket.Close(); socket.TryDispose(); } RemoteEndPoint = null; } } }