I'm interested to know how can I detect (at the server side ) that a socket connection failed when the client computer has the network cable plugged out or is hard reseted. This would be useful for a client server project in c#.
Currently I'm able to detect socket exceptions only when client closes the application and implicitly the socket.
Googling a bit I found abou the FD_CLOSE IEvent of WSAAsyncSelect . Would this work for the cases that I've described above ?
Take a look at this answer: Instantly detect client disconnection from server socket
UPDATE
Ok, i figured out what you are talking about. There is no way you can find out on the server if client cable is unplugged or something happens to it's network. You will simply not get any response from that client any more. Only way i can see is provided in link at beginning of this answer.
There is WSAEventSelect native method inside of Ws2_32.dll (Winsock2), but it's only used to detect network unavailability reason on local machine (where app runs).
I took a look inside System.Net.NetworkInformation.NetworkChange class source code and there you can see that everything related to WSAEventSelect is about local machine (in your case server).
Related
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 am working on a Peer-to-Peer chat program but have ran across an issue: Running the client and server simultaneously. I do not want a dedicated server to manage connections. I believe the solution may be asynchronous direct connections, but I am not sure.
What I am trying to accomplish is to be able to run the program between two hosts, the program will be started and begin trying to connect to an ip address specified by a text box. At the same time, it will also start listening for incoming connections on the localhost ip address.
***I am using tcp, because on the off chance something is corrupted the message will not be able to be read (it is encrypted)
Issues:
1) It is conceivable a client could be waiting for a period of time before the other program tries to connect. So should some form of a loop must be utilized? If so, how?
2) I assume I need to use multi-threading, with one thread for the server part and one thread for the client part, but an issue is keeping them from hanging. Since both programs are identical there way be a way to listen and simultaneously attempt to connect to the other host.
3) I am also having trouble with making my server listen for connections to it, and do not know how to automatically have it pull the ip address from my computer.
Thanks for any help.
EDIT: This is on a LAN only.
Everything you need to know is in Microsoft's docs.
http://msdn.microsoft.com/en-us/library/w89fhyex.aspx
I have a C# app where a server and some clients communicate from different machines using sockets.
Most of the time, the server detects a dis-connect correctly when it receives 0 bytes in the sock.Receive(...) call. But when there is a hardware issue (say a network cable is unplugged), there is a problem. One server thread continues to block on sock.Receive(...) because it doesn't know the connection is lost. I was going to add a heartbeat message to detect this, but I wanted to test it in dev.
But I'm not sure how I can test this case without an actual hardware issue. Even when I just kill the client process, the socket somehow manages to dis-connect gracefully (that is, the server does a read of 0 bytes). It's only when I physically unplug the client machine from the network that I see this issue.
Is there any way that I can simulate this issue in dev?
You need to explicitly inform WinSock that you don't want it to clean up for you after closing the socket. This is done by setting LingerState as such:
socket.LingerState = new LingerOption(true, 0);
socket.Close();
LingerState is a bit confusing, because if you disable the linger, WinSock will actually linger but just not block your program. You have to enable the linger and set the linger timeout to zero in order to force WinSock to drop the connection.
P.S. If you want some info about keepalive packets (heartbeats), I've written a blog entry on the subject.
Update:
I re-read your question (and comment), and my answer is wrong...
The code above will simulate an abortive close, not a half-open situation. There isn't a way to simulate a half-open situation in software; you need to unplug an Ethernet cable that is not attached to either computer in order to test this (e.g., yank the cable between the two switches in this configuration: computer A <-> switch <-> switch <-> computer B).
I want to know how I can send or recieve data over internet to/from a computer in subnet
(this is specially in context to PPP users bcoz getting static IP is not so much in practice).
I actually want to create an application which can transfer file between 2 specific computer in WAN.
so what are things I need to know about to do the same..(ex. PRESENT IP or MAC ADDRESS etc..)
PROGRAMATICAL EXPLANATION ALTHOUGH PREFFERED,BUT IS NOT NECCESARY...
FTP?
There is a vast torrent of useful results in google, I seriously suggest to google before you ask here.
For instance, have a look at the top result: http://www.devarticles.com/c/a/C-Sharp/Network-Programming-in-C-sharp/
Apart from that, FTP, as suggested by Colin, may be what you're looking for. If you're new to using FTP in C# have a look at http://www.google.com/search?q=c%23+ftp
Put the information on a public IP server, so both computers keep polling if there is new data and send / download that data as needed. A single text file can hold necessary flags such as paths and other info you need.
server just need to be a web server, which means IIS or similar should be installed.
I'm thinking part of your question has to do with one of the computers not having a static IP address. If the two computers, A & B, don't know each others IP address, then an alternative is to use a server. Either A can store the information on the server to be picked up by B, or A can register his current IP address on the server for B to lookup and then connect to A, assuming firewalls don't interfere. Another scheme is that A and B can simultaneously connect to the server, and the server can relay data between the two.
Of course, all of this communication would be done using techniques such as those suggested by mafutrct and Colin.
This question sounds to me like the difficulties of NAT Traversal and trying to establish peer-to-peer connectivity over the Internet. I stumbled on this question researching the best way to set up Internet connectivity to a device that is sitting behind a firewall. I am assuming that the device behind the firewall has to initiate the connection, that a Internet server application (on a Public IP address) to at least manage the initiation of the connection is required, and the Internet server application may also have to act as a relay if the difficulties of NAT is not able to be traversed.
http://en.wikipedia.org/wiki/NAT_traversal
http://en.wikipedia.org/wiki/Peer-to-peer
A good example of this is LogMeIn. Where the application is installed on the computer that needs to be accessible over the Internet, that application communicates with the LogMeIn Internet servers, you can establish a connection to that computer either by initiating through the LogMeIn servers and connecting peer-to-peer over port 80/443 using NAT Traversal (this would be establishing a peer-to-peer connection) or by initiating through the LogMeIn server and the LogMeIn server acting as a relay if peer-to-peer is unable to be established.
Please note; you must have an application (something running) on both ends of the connection on the Internet, there is no other way. Just like FTP that was mentioned earlier (FTP Client, FTP Server)... but in this case it is peer-to-peer (basically you are writing your own Client and Server... or if you have to use a relay... Client--Relay--Server
http://en.wikipedia.org/wiki/LogMeIn
"The service connects the remote desktop and the local computer using SSL over TCP or UDP and utilizing NAT traversal techniques to achieve peer-to-peer connectivity when available."
The part I don't know is can the relay go in both directions; and I am figuring the device behind the firewall must have to constantly manage the open connection to the Internet Server that is the relay. Those are the questions I am wrestling with now.
Also, you may want to check out this post.
C# byte streams through TCP
From that time, till this date I have encounter so many problems with these four kinds of NAT that basically without an external server you cant do anything.
This is because, one computer can never find where the other one is located as suggested in the pic.
Here PC 'A' will never come to know about the port that corresponds to PC 'B' on R2B without an external server.Even more, if somehow u come to know about the ports you are still in a situation that the router wont allow you to access it if the request hasn't been made for your IP.
When we send a packet from a udp port we receive an exception if the network returns an ICMP host unreachable. The exception doesn't tell us anything useful (like the contents of the ICMP packet).
No problem, we'll just listen for ICMP and that will give us the info we need, while ignoring the exception on the UDP port. So, open a raw socket, listen for ICMP packets and go from there.
Works fine in development (Win XP) but in production on server 2008 it appears the security context the exe is running in must have admin rights to be able to open a raw socket. This is useless for a service. If I understand what Microsoft are saying then the only way we can do what we want is run our service under an account with admin rights. Feels a bit like sledgehammer for a peanut not to mention a potential security hole that goes with having a network facing service running under an admin account.
I really hope I am wrong here but I can't seem to find anything that contradicts the above.
Anyone got any comments / hints or sympathy?
Rather than listening for ICMP responses to your failed UDP sends, why not send a brand spanking new ICMP echo request?
When you get the exception, you could PInvoke the IcmpSendEcho() function (from Win32 IP Helper API) to generate a new ICMP echo request yourself. The key bit is that the function returns a buffer with the echo reply in it, including status codes e.g. IP_DEST_HOST_UNREACHABLE.
I don't think you need any special privileges to do this, so it should be easier than listening for ICMP replies with raw sockets.
You will need three functions: IcmpCreateFile(), IcmpSendEcho() and IcmpCloseHandle() - PInvoke.net has the necessary interop details:
http://www.pinvoke.net/default.aspx/icmp/IcmpCreateFile.html
http://www.pinvoke.net/default.aspx/icmp/IcmpSendEcho.html
http://www.pinvoke.net/default.aspx/icmp/IcmpCloseHandle.html
Had exactly the same issue myself Listen for ICMP packets in C#. Actually looks like your issue is windows permissions so that post won't help.
One area I was planning on delving into a bit further is to check whether there is anymore information in the SocketException generated by the UdpListener. It just seems unreasonable that as Windows is using the ICMP packet to generate the exception it wouldn't be recording the information in that packet somewhere.
Like you I have not been able to get very far with getting the ICMP info out of the exception information at the .Net level but I want to see if there is anything further that can be obtained with the Win32 API such as GetLastError or some other calls specifically for WinSock32.
From the MSDN website:
To use a socket of type SOCK_RAW
requires administrative privileges.
Users running Winsock applications
that use raw sockets must be a member
of the Administrators group on the
local computer, otherwise raw socket
calls will fail with an error code of
WSAEACCES. On Windows Vista and later,
access for raw sockets is enforced at
socket creation. In earlier versions
of Windows, access for raw sockets is
enforced during other socket
operations.
To get around this problem in my project , I've created a Windows service that serves as a network proxy for our UI application. The Windows serves runs under the local admin account in order to get around the limitations. The application connects to the service using WCF, telling it what kind of socket to open and what filter(s) to apply. The data is then sent back via callback using Protocol Buffers for encoding (at least that's the plan - the callback part is still in progress).