I have created a small application which log data from client to server. I want to get the status of client application when it exit the application from task messenger. How do i get the client status.
Just like in skype.
I user exits skype form task messenger another user's skype shows got logged out this user.
You could have the client send small heartbeats in regular intervals. If those heartbeats stop coming you know that the client has shut down (either the process was killed, the application shut down, the computer shut down, the network connection dropped, etc...).
Cant you catch SocketException and also check for receiving zero bytes. If you receive zero bytes the other side closed the connection cleanly. If you get a SocketException with the SocketErrorCode set to ConnectionReset then you can also assume the other side is gone. The only thing you won't pick up is half open connections. For that you will need some sort of keep alive packet as Andreas suggested.
Related
Alright, so here's my thinking:
If two requests were made to one server at the same time, would one be denied, and if so, how could you keep something like that from happening?
I currently have a server set up for a chat application I'm making, and it basically starts a TCP/IP connection, waits for a client, reads the data sent from them, sends something back, disconnects, and repeats. That way, the server never stops running, and as many requests as you want could be made.
However, what if a client was starting up while another program was using the server. If one program was getting a file from the server while the other one was starting up, and the starting up one needed data from the server, but it was already busy, what would happen?
Would the startup wait until the server was available, or would it just go straight to an error (since no connection was available). If so, this could be really bad, since then the user wouldn't have all the data, like the list of his friends, or a few chats. How could you fix this?
My idea would be that you could have a while loop set up so that it keeps queuing the server until it gets a response. Is this the right way to go about this?
No, the client should assume that the server is always available. You'll see that the basic Socket.Listen(int32) method (which TcpListener acts as a wrapper for) takes one parameter, backlog:
Listen causes a connection-oriented Socket to listen for incoming connection attempts. The backlog parameter specifies the number of incoming connections that can be queued for acceptance. To determine the maximum number of connections you can specify, retrieve the MaxConnections value. Listen does not block.
Most server implementations start with something like the following:
socket.Listen(10); // You choose the number
while (true)
{
var client = socket.Accept();
// Spawn a thread (or Task if you prefer), and have that do all the work for the client
var thread = new Thread(() => DoStuff(client));
thread.Start();
}
With this implementation, there is always a thread listening for new connections. When a client connects, a new thread is created for it, so the processing for that client doesn't delay/prevent more connections from being accepted on the main thread.
Now, if a few new connections come in faster than the server can create new threads, then the new connections will be put in the backlog automatically (I think at the OS level) - the backlog parameter determines how many pending connections can be in the backlog at once.
What if the backlog fills up completely? At this point, you need a second server, and a load balancer to act as a middle-man, directing half the requests to the first server, and half the requests to the second server.
Logic here is simple.
Server starts listening and begins accept clients.
Client tries to connect to the server. You can simply do nothing if server isn't running or you can implement some reconnect logic notifying client about unsuccessful connection attempts.
Lets assume that server was running when client tried to connect. You are talking about multi client application. You shouldn't disconnect the client. You should add connected client to the list of connected clients.
Then, when some of the clients connects to the server and there are some other already connected clients and sends some message. You receive that message via client socket and then you broadcast the message to all other connected clients except one that is sending the data.
I have a c# .net4 application that listens on a socket using BeginReceiveFrom and EndRecieveFrom. All works as expected until I put the machine to sleep and then resume.
At that point EndReceieveFrom executes and throws an exception (Cannot access a disposed object). It appears that the socket is disposed when the machine is suspended but I'm not sure how to handle this.
Do I presume that all sockets have been disposed and recreate them all from scratch? I'm having problems tracking down the exact issue as remote debugging also breaks on suspend/resume.
What happens during suspend/resume very much depends on your hardware and networking setup. If your network card is not disabled during suspend, and the suspend is brief, open connections will survive suspend/resume without any problem (open TCP connections can time out on the other end of course).
However, if your network adapter is disabled during the sleep, or it is a USB adapter that gets disabled because it is connected to a disabled hub, or your computer gets a new IP address from DHCP, or your wireless adapter gets reconnected to a different access point, etc., then all current connections are going to be dropped, listening sockets wil no longer be valid, etc.
This is not specific to sleep/resume. Network interfaces can come up and go down at any time, and your code must handle it. You can easily simulate this with a USB network adapter, e.g. yank it out of your computer and your code must handle it.
I've had similar issues with suspend/resume and sockets (under .NET 4 and Windows 8, but I suspect not limited to these).
Specifically, I had a client socket application which only received data. Reading was done via BeginReceive with a call-back. Code in the call-back handled typical failure cases (e.g. remote server closes connection either gracefully or not).
When the client machine went to sleep (and this probably applies to the newer Windows 8 Fast Start mode too which is really just a kind of sleep/hibernate) the server would close the connection after a few seconds. When the client woke up however the async read call-back was not getting called (which I would expect to occur as it should get called when the socket has an error condition/is closed in addition to when there is data). I explicitly added code on a timer to the client to periodically check for this condition and recover, however even here (and using a combination of Poll, Available and Connected to check if the connection was up) the socket on the client side STILL appeared to be connected, so the recovery code never ran. I think if I had tried sending data then I would have received an error, but as I said this was strictly one-way.
The solution I ended up using was to detect the resume from sleep condition and close and re-establish my socket connections when this occurred. There are quite a few ways of detecting resume; in my case I was writing a Windows Service, so I could simply override the ServiceBase.OnPowerEvent method.
I'm using SignalR (0.5.3) Hubs for a chat app where each keystroke is sent to the server (saved in the DB), relayed to all clients and a return value (a string token of sorts) is sent back from the server.
It works fine, until the app pool recycles, then it stops relaying the keystrokes to all the clients (because the in-memory server state is lost I suppose) and the server doesn't return back any values as well. At this point, I suppose all requests via SignalR are queued by IIS and then processed once the app pool has been recycled.
My question is how can I handle this scenario so that all clients are aware of the server unavailability/delay due to app pool recycle, notify the user to wait for a while and then resume operation on reconnect?
There's two options.
For 0.5.3 you can detect when the client goes into "reconnecting" or is "disconnected" and notify the user that there is server issues. Keep in mind in most situations the client will not actually know that it is disconnected if the server just goes away.
OR
If you wait for the next release (1.0alpha) we will take care of the bulk of this for you. On lack of a server we will trigger an onConnectionSlow event which will then result in the client shifting into the "reconnect" (if it does not receive any info) state until the server comes back online. The client will also know if the server goes away (we're adding this functionality) for edge cases such as an app pool recycle.
Hope this helps!
I was wondering how to handle a situation where you successfully connected two processes through named pipe (one server and one client), and suddenly (for some reason) the server process ends.
What happens to the pipe? Does it close?
What happens to information being sent by the client to the server? Does it get lost?
How can the client know if the server is down?
All The Best,
Gil
If you are using System.IO.Pipes and NamedPipeServerStream for example, you would get IOException when a pipe is broken or disconnected.
When you are using NamedPipeClientStream for reading in information from server, I believe the client would wait till a connection is established on the NamedPipeClientStream.Connect() call alternative you could use NamedPipeClientStream.Connect(Int32) option to timeout a connection after a predetermined period. Apart from that the StreamReader.ReadLine() is also capable of throwing IOException when something does not go well.
The NamedPipeClientStream.IsConnected would be a simple way to determine if the client is connected successfully to the server or if it is disconnected, closed, or broken.
I am facing a wierd socket connection problem in .net windows application.I am using socket from .net to asynchonously communicate to a legacy intersystems cache database.I have a specific timeout value in the application, when the timeout occurs, user is prompted to stay connected to the application. When I say stay connected, socket is not being reset. I set timeout to 30 mins and say stay connected for first idle time.Then when I navigate the application it works fine.
If with out navigating in the application and say stay connected second time, and navigate in the app I am getting socket "host refused" connection error. This I can assume may be socket is terminated. But the wierd part is if I set the application timeout to 10 mins, then also I am getting socket error second time. When I check the sockets connected property, it is still true. I am not catching exception when I call sockets Send method. But the data is not passed from the socket.I have checked the other .net code. it is fine. This problem also occurs rarely, only 1 in 10 times. Any suggestions will be greatly helpful.
This sounds like a typical issue resulting from firewalls or other TCP settings.
Firewalls might silently disconnect the connection if it is idle more than x seconds.
As the TCP protocol does not generate an event in such a case (similar like just removing the network cable), it is highly recommended to send ping message every x seconds, so that the firewall stays open and that you can be sure to be connected. if the ping is missed, the server disconnects the client.