Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>When you exit your server, you should call _tcpListener.Stop() to close the main socket that the server is listening on.</p> <p>Edit: You could also try to call _listenerThread.Join() in your stop button click, to wait for the listener thread to finish, before starting the next one.</p> <pre><code>private void btnStop_Click(object sender, EventArgs e) { if (_tcpListener != null) { _keepRunning = false; if (_tcpListener.Server.Connected) { _tcpListener.Server.Disconnect(true); _tcpListener.Stop(); if (_clientSocket != null) { _clientSocket.Close(); _clientSocket = null; } _listenerThread.Join(); } } labelServerStatus.Text = "Server is stopped"; comboBoxPorts.Enabled = true; btnStart.Enabled = true; btnStop.Enabled = false; } </code></pre> <p>EDIT 2:</p> <p>here is a windows form that does similar to your server. I didn't need a client, just use "telnet localhost 49152" from a command prompt to 'pretend' to be the client connecting.</p> <pre><code>public partial class Form1 : Form { private TcpListener _tcpListener; private bool _keepRunning; private Thread _listenerThread; private Socket _clientSocket; public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { var address = IPAddress.Parse("127.0.0.1"); _tcpListener = new TcpListener(address, 49152); _keepRunning = true; _listenerThread = new Thread(Listen); _listenerThread.Start(); button1.Enabled = false; button2.Enabled = true; } private void Listen() { try { _tcpListener.Start(); } catch (Exception e) { MessageBox.Show(e.Message); return; } _keepRunning = true; while (_keepRunning) { try { _clientSocket = _tcpListener.AcceptSocket(); var buffer = new byte[8192]; var bytesReceived = _clientSocket.Receive(buffer); var checkString = String.Empty; if (_keepRunning) { // bytesReceived can be 0 if the remote socket disconnected if (bytesReceived &gt; 0) { checkString = Encoding.ASCII.GetString(buffer, 0, bytesReceived); // Client is waiting to know operation is complete- so send him some char... var encoder = new ASCIIEncoding(); _clientSocket.Send(encoder.GetBytes("v")); } if (_clientSocket.Connected) _clientSocket.Disconnect(true); } _clientSocket.Close(); } catch (Exception ex) { // really should do something with these exceptions } } } private void button2_Click(object sender, EventArgs e) { if (_tcpListener != null) { _keepRunning = false; if (_tcpListener.Server.Connected) { _tcpListener.Server.Disconnect(true); } _tcpListener.Stop(); if (_clientSocket != null) { _clientSocket.Close(); _clientSocket = null; } _listenerThread.Join(); } button1.Enabled = true; button2.Enabled = false; } } </code></pre> <p>There are a lot of problems with this code, e.g. sharing variables across threads etc. but on my machine the Join doesn't seem to block for any length of time. The problem with _keepRunning is that on certain systems it's possible for one thread to not see the change from true to false, because it gets optimised or cached. You should really use some form of thread synchronisation, make it volatile, or wrap it in a lock etc. I'd suggest you have a read <a href="http://www.albahari.com/threading/" rel="nofollow">here</a> about this. I'd also suggest you have a read up on Sockets too, or if as other commenters have mentioned, if you aren't interested in learning about all the idiosyncrasies of sockets and threading, perhaps you should look for a higher level library that hides it all?</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