Note that there are some explanatory texts on larger screens.

plurals
  1. POdisconnect/close a client
    text
    copied!<p>I have a simple client-server application which works like this: the server is always listening (in a separate thread) for a client connection (which sends the name of process that it wants the server to kill).</p> <p>Here is the server:</p> <pre><code>private void btnStart_Click(object sender, EventArgs e) { _port = int.Parse(comboBoxPorts.SelectedItem.ToString()); _tcpListener = new TcpListener(_ipAddress, _port); _keepRunning = true; _listenerThread = new Thread(Listen); HandleListenerThreadStartListenEvent += HandleListenerThreadStartedEventMethod; ListenerThreadStartedEvent += HandleListenerThreadStartListenEvent; _listenerThread.Start(); } private void btnStop_Click(object sender, EventArgs e) { if (_tcpListener != null) { _keepRunning = false; if (_tcpListener.Server.Connected) { _tcpListener.Server.Disconnect(true); } _tcpListener.Stop(); } labelServerStatus.Text = "Server is stopped"; comboBoxPorts.Enabled = true; btnStart.Enabled = true; btnStop.Enabled = false; } private void Listen() { try { _tcpListener.Start(); OnListenerThreadStartListenEvent(); // just update the GUI } catch(Exception e) { MessageBox.Show("Port " + _port + " is NOT available." + Environment.NewLine + "Please choose another one: " + e.Message); return; } _keepRunning = true; string ballonMessage = "Socket Server Running at " + _ipAddress + ", port: " + _port; notifyIcon1.ShowBalloonTip(2000, "Simplex Listener", ballonMessage, ToolTipIcon.Info); while (_keepRunning) { try { #region using AcceptSocket() _clientSocket = _tcpListener.AcceptSocket(); string checkString = string.Empty; IPAddress ipOfClient = ((IPEndPoint) _clientSocket.LocalEndPoint).Address; notifyIcon1.ShowBalloonTip(2000, "Simplex Listener", "New client has connected from ip " + ipOfClient, ToolTipIcon.Info); byte[] buffer = new byte[SIZE_OF_BUFFER]; int bytesReceived = _clientSocket.Receive(buffer); // Concatenate chars as bytes to a received string. for (int i = 0; i &lt; bytesReceived; i++) checkString += Convert.ToChar(buffer[i]); //..... getting the name of process and kill it (and than open it... RestartProcess(nameOfProcess, windowName, pathToExeFile); // Client is waiting to know operation is complete- so send him some char... ASCIIEncoding encoder = new ASCIIEncoding(); _clientSocket.Send(encoder.GetBytes("v")); _clientSocket.Disconnect(true); _clientSocket.Close(); #endregion } catch (Exception ) { } } } </code></pre> <p>The client side:</p> <pre><code>public void RestartTheSoftwareInServerComputer(string ipOfServer, int portNumber) { TcpClient client = new TcpClient(); if (_serverEndPoint == null) { _serverEndPoint = new IPEndPoint(IPAddress.Parse(ipOfServer), portNumber); } client.Connect(_serverEndPoint); // Send the command to the server: NetworkStream clientStream = client.GetStream(); ASCIIEncoding encoder = new ASCIIEncoding(); byte[] buffer = encoder.GetBytes("....detailsOfProcess...."); clientStream.Write(buffer, 0, buffer.Length); clientStream.Flush(); // Now, wait for the server's response [which means the process had been restart]. NetworkStream stream = client.GetStream(); byte[] bytes = new byte[5]; stream.Read(bytes, 0, 5); string response = Encoding.UTF8.GetString(bytes, 0, 1); if (response.Equals("x")) { throw new Exception("Failed to restart X software."); } stream.Close(); client.Close(); } </code></pre> <p>When I stop and restart the server (when no client had connected), then everything is OK.</p> <p>The problem is when the server got some client connected, and is restarted, then the client has disconnected and the server needs to be restarted. When we hit the "START SERVER" again it will get the exception:</p> <blockquote> <p>Only one usage of each socket address (protocol/network address/port) is normally permitted.</p> </blockquote> <p>How should I close the port?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload