I am writing a client-server application using TCP Sockets. The server is written in C# using Visual Studio 2010 (.NET 4.0). The server allows multiple client connections at the same time therefore I am using the Async. style. The server needs to connect to a database (MySQL) and while the server program is running I need to interact with the database. For this reason I am using a BackgroundWorker to run the infinite listening loop (that will Accept Clients) in order to prevent the interface from freezing and be able to access the database from the visual interface.
Everything is working fine unless when the server program losses focus. Examples of losing focus are: the PC that is running the server program starts the screensaver, you click on the clock on the task-bar to see the time, you open another widow (windows explorer, calculator…). If the server program looses focus and a client tries to connect, the server closes completely! If I am running the server from Visual Studio it does not throw any error or exception. If I am running a released version of the server, Microsoft Windows will show the “Programming not responding…” dialog.
Here is how my code is structured:
Variables in the main class:
const int portNo = 12345;
static System.Net.IPAddress localAdd = System.Net.IPAddress.Parse("192.168.1.67");
static TcpListener tcpListenerReadWrite = new TcpListener(localAdd, portNo);
In the main Form a button starts the server:
private void button1_Click(object sender, EventArgs e)
{
tcpListenerReadWrite.Start();
backgroundWorker1.RunWorkerAsync();
}
The background worker DoWork function:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
while (true)
{
ChatClient clientRead = new ChatClient(tcpListenerReadWrite.AcceptTcpClient());
}
}
In the Server Class, the constructor is as follows:
public ChatClient(TcpClient client) //constructor
{
_client = client;
_clientIP = client.Client.RemoteEndPoint.ToString();
//start reading data from the client in a separate thread
data = new byte[_client.ReceiveBufferSize];
_client.GetStream().BeginRead(data, 0, Convert.ToInt32(_client.ReceiveBufferSize), ReceiveMessage, client);
}
When a message is received by the server:
public void ReceiveMessage(IAsyncResult asyncResult)
{
//read received message from client
}
Two final notes: (1) when a client connects to the server the first thing it does is sending a message to the server like a Hello message, (2) before writing the server in a visual interface I was testing it in a Console mode and this problem was not existing, the screensaver used to run and nothing happened. Sure in the console mode I didn’t use any BackgroundWorker.
Any ideas why the server is crashing?
I found what was crashing my server (it took me some time because I was lately focusing on the client programming, it is today when I returned to the server programming). As @Moo-Juice suggested, it is a problem related to accessing the UI. In fact here is the scenario that was causing the crash:
backgroundWorker.textBoxthat a client has connected. //here is the problembackgroundWorker.ReportProgressmethod.To review the problem, the server crashes only if the focus is not on the program (a screen saver is running for example), but no crashing if the focus is on the program and logging is working. When I stopped the logging things went OK. So know I know the source of the problem but I don’t know why it is causing the crash; as I know the
ReportProgressis designed to be use to report progress to the user interface. Anyway I will try to solve this now especially that I know from where to go. In case you are interested to see how I was doing the logging here is the function that I used:And here is the
ReportProgressfunction:Nothing so fancy but enough to cause me headache 🙂 Thanks for all your help.