async void Handle() { // Listen for connections while (true) { if (!IsListening) { return; } Socket handler; try { // this operation is canceled when socket gets disposed handler = await listeningSocet.AcceptAsync(); StartReceivingMessages(handler); } catch (SocketException) { return; } incomingConnections.Add(handler); ConnectionsCountChanged?.Invoke(this, new ConnectionsCountChangedEventArgs(ConnectionsCount)); } }
// ==== ==== async void StartReceivingMessages(Socket socket) { byte[] array = new byte[BufferSize]; var segment = new ArraySegment <byte>(array); while (true) { if (!socket.Connected) { StopHandling(socket); return; } int bytesRead; try { bytesRead = await socket.ReceiveAsync(segment, SocketFlags.None); } catch (Exception) { StopHandling(socket); return; } string message = Encoding.Unicode.GetString(array, 0, bytesRead); if (string.IsNullOrWhiteSpace(message)) { StopHandling(socket); MessageBox.Show("One of devices must have been disconnected", "Error: empty string received"); return; } if (message == IpAddressMessage) { Disconnect(); MessageBox.Show("Disconnected due to loops in network", "Connection terminated"); ConnectionsCountChanged?.Invoke(this, new ConnectionsCountChangedEventArgs(ConnectionsCount)); return; } if (IsDisconnectingMessage(message)) { Disconnect(); var remoteEndPoint = ParseIpEndPoint(message); await Connect(remoteEndPoint); } MessageReceived?.Invoke(this, new MessageReceivedEventArgs(message)); await Send(message, socket); } }
public override void Disconnect() { bool actuallyDisconnecting = HasOutcomingConnection; outcomingConnection?.Shutdown(SocketShutdown.Both); outcomingConnection?.Close(); outcomingConnection = null; if (actuallyDisconnecting) { ConnectionsCountChanged?.Invoke(this, new ConnectionsCountChangedEventArgs(ConnectionsCount)); } }
async Task Connect(EndPoint remoteEndPoint) { // Create a TCP/IP socket. var client = new Socket(remoteEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); // Connect to the remote endpoint. await client.ConnectAsync(remoteEndPoint); outcomingConnection = client; StartReceivingMessages(client); // This action should terminate current connection if loops are present await Send(IpAddressMessage); ConnectionsCountChanged?.Invoke(this, new ConnectionsCountChangedEventArgs(ConnectionsCount)); }
public override void TerminateIncomingConnections() { // do I really need to lock? // Probably not, but I'm afraid to modify this old code lock (incomingConnections) { foreach (var socket in incomingConnections) { socket.Shutdown(SocketShutdown.Both); socket.Close(); } incomingConnections.Clear(); } ConnectionsCountChanged?.Invoke(this, new ConnectionsCountChangedEventArgs(ConnectionsCount)); }
void StopHandling(Socket socket) { if (socket == outcomingConnection) { Disconnect(); return; } if (incomingConnections.Remove(socket)) { ConnectionsCountChanged?.Invoke(this, new ConnectionsCountChangedEventArgs(ConnectionsCount)); return; } // throw new InvalidOperationException("StopHandling() was given a socket that doesn't belong to client"); // MessageBox.Show("StopHandling() was given a socket that doesn't belong to client", "Warning"); }
public MainWindowModel(string login) { Login = login; Client = new Client(); Window = new MainWindow { Title = Login }; Window.Closing += OnWindowClosing; Window.SendRequested += OnSendRequested; Window.MessageTextChanged += (sender, args) => Window.IsSendButtonEnabled = Client.HasConnections && !string.IsNullOrEmpty(args.NewText); Window.SettingsWindowRequested += OnSettingsWindowRequested; Client.MessageReceived += (sender, args) => Window.AddMessage(args.Message); Client.ConnectionsCountChanged += (sender, args) => ConnectionsCountChanged?.Invoke(sender, args); ConnectionsCountChanged += (sender, args) => Window.SetConnectionsCount(args.Count); }