/// <summary> /// Метод закрытия соединения с клиентом /// </summary> /// <param name="client">Экземпляр данных о клиенте</param> private void CloseConnection(ConnectionValue client) { if (client != null) { lock (Сonnections) Сonnections.Remove(client); if (client.Socket != null) { try { if (client.Socket.Connected) { client.Socket.Shutdown(SocketShutdown.Both); } } catch (Exception ex) { CallErrorServer(ServerErrorType.CloseConnection, ex.Message); } client.Socket?.Close(); client.Socket?.Dispose(); client.Socket = null; CallDisconnected(client); } } }
/// <summary> /// Метод отправки сообщения (калбэк) /// </summary> /// <param name="result"></param> private void SendCallback(IAsyncResult result) { ConnectionValue connection = (ConnectionValue)result.AsyncState; try { if (connection.Socket != null && connection.Socket.Connected) { // Отправка сообщения завершена int send_size = connection.Socket.EndSend(result); CallSendResult(connection.SocketID, send_size); } else { CloseConnection(connection); } } catch (SocketException exc) { CallErrorServer(ServerErrorType.SendDataError, exc.Message); CloseConnection(connection); } catch (Exception exc) { CallErrorServer(ServerErrorType.SendDataError, exc.Message); CloseConnection(connection); } }
/// <summary> /// Отправка масива байт /// </summary> /// <param name="client_id">ID клиента, полученный при событии подкулючения</param> /// <param name="data">массив байт для отправки</param> public void Send(IntPtr client_id, byte[] data) { ConnectionValue client = null; lock (Сonnections) client = Сonnections.Find(o => o.SocketID.Equals(client_id)); if (client != null) { try { client.Socket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(SendCallback), client); } catch (SocketException exc) { CallErrorServer(ServerErrorType.SendDataError, exc.Message); CloseConnection(client); } catch (Exception exc) { CallErrorServer(ServerErrorType.SendDataError, exc.Message); CloseConnection(client); } } else { CallErrorServer(ServerErrorType.EmptyClientError, client_id.ToString() + " - not found"); } }
/// <summary> /// Метод асинхронного принятия новых подключений /// </summary> /// <param name="result"></param> private void AcceptCallback(IAsyncResult result) { lock (locker) { if (IsListeningStatus != false) { ConnectionValue connection = new ConnectionValue(); try { // Завершение операции Accept connection.Socket = ServerSocket.EndAccept(result); connection.SocketID = connection.Socket.Handle; connection.Buffer = new byte[SizeBuffer]; connection.RemoteIP = ((IPEndPoint)connection.Socket.RemoteEndPoint).Address.ToString(); connection.RemotePort = ((IPEndPoint)connection.Socket.RemoteEndPoint).Port; lock (Сonnections) Сonnections.Add(connection); // Начало операции Receive и новой операции Accept connection.Socket.BeginReceive(connection.Buffer, 0, connection.Buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), connection); //Сообщаем о новом подключении CallConnected(connection); } catch (SocketException exc) { CallErrorServer(Sockets.ServerErrorType.AcceptError, exc.Message + exc.ToString()); CloseConnection(connection); } catch (Exception exc) { CallErrorServer(Sockets.ServerErrorType.AcceptError, exc.Message + exc.ToString()); CloseConnection(connection); } finally { try { if (ServerSocket != null && ServerSocket.IsBound) { ServerSocket?.BeginAccept(new AsyncCallback(AcceptCallback), null); } } catch (Exception ex) { CallErrorServer(Sockets.ServerErrorType.AcceptError, ex.Message + ex.ToString()); } } } } }
/// <summary> /// Метод асинхронного получения сообщений /// </summary> /// <param name="result"></param> private void ReceiveCallback(IAsyncResult result) { ConnectionValue connection = (ConnectionValue)result.AsyncState; try { if (connection.Socket != null && connection.Socket.Connected) { int read_size = connection.Socket.EndReceive(result); if (read_size > 0) { connection.BufferBuilder.Append(connection.Buffer, read_size); if (connection.Socket.Available <= 0) { //Вызываем событие по окнчанию чтения данных от сокета CallReceive(connection.SocketID, connection.BufferBuilder.Data); connection.BufferBuilder.Clear(); } connection.Socket.BeginReceive(connection.Buffer, 0, connection.Buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), connection); } else { CloseConnection(connection); } } else { CloseConnection(connection); } } catch (SocketException exc) { CallErrorServer(ServerErrorType.ReceiveDataError, exc.Message); CloseConnection(connection); } catch (Exception exc) { CloseConnection(connection); CallErrorServer(ServerErrorType.ReceiveDataError, exc.Message); } }
/// <summary> /// Вызов события об отключении /// </summary> /// <param name="id">ID сокета</param> /// <param name="ip">IP адрес подклоючения</param> /// <param name="port">Удаленный порт</param> private void CallDisconnected(ConnectionValue client) { Task.Factory.StartNew(() => { ClientDisconnect?.Invoke(this, new Arguments.ClientConnectionArgs(client.SocketID, client.RemoteIP, client.RemotePort)); }); }