This most likely happens because you use synchronous (blocking) socket IO. Your server application most likely blocks on the recv()
/read()
, which blocks your thread's execution until some data arrives; it then processes the data and returns to blocked state. Hence, your button is rendered by GTK as pushed.
There are, basically, two generic approaches to this problem. The first one is threading. But I would recommend against it in the simpler applications; this approach is generally error-prone and pretty complicated to implement properly.
The second approach is asynchronous IO. First, you may use select()
/poll()
functions to wait for one of multiple FDs to be signalled (on such events as 'data received', 'data sent', 'connection accepted'). But in a GUI application where the main loop is not immediately available (I'm not sure about GTK, but this is the case in many GUI toolkits), this is usually impossible. In such cases, you may use generic asynchronous IO libraries (like boost asio). With GLIB, IIRC, you can create channels for socket interaction (g_io_channel_unix_new()
) and then assign callbacks to them (g_io_add_watch()
) which will be called when something interesting happens.
The idea behind asynchronous IO is pretty simple: you ask the OS to do something (send data, wait for events) and then you do other important things (GUI interaction, etc.) until something you requested is done (you have to be able to receive notifications of such events).
So, here's what you may want to study next:
select()
/poll()
(the latter is generally easier to use)- boost asio library
- GLIB channels and asynchronous IO