What I want to do is call some code when the internet connection is established or restored.
I know there are solutions out there that let me test whether an internet connection is active or not, but I am wondering if there is a way for a function to be triggered by the internet connection becoming active.
If not, what is the best workaround? Checking for a connection every x seconds? Thanks.
The SCNetworkReachability APIs can be configured to generate notifications when the reachability status of an IP address or hostname changes. Create a SCNetworkReachabilityRef, then set a callback, and it will be called when a network change is detected.
Related
I have a script (I don't have the code example here at the moment but I used IO::Async) which connects to socket on a remote server and listens. Client usually just listens for new data.
Problem is that the client is not able to detect if network problems occur and the socket connection is gone.
I used IO::Async and I also tried it with IO::Socket. Handle is always "connected" after the initial connection is established.
If the network connection is established again the socket connection is naturally still lost because the script has no idea that it should reconnect.
I was thinking to create some kind of "keepAlive" which "pings" (syswrite) the socket every X seconds (if nothing new came through socket) to check whether the connection is still there.
Is this the correct way to do it or is there maybe an another more creative or cleaner solution?
You can set the SO_KEEPALIVE socket option which, for TCP, sends periodic keepalive messages, and may help detect this condition. If this is detected, you will be delivered an EOF condition (most likely causing the containing IO::Async::Stream to fire on_read_eof).
For a better solution you might consider some sort of application-level keepalive message, such as IRC's PING command.
The short answer is there is no default way to automatically detect a dropped socket in perl.
Your approach of pinging would probably work pretty well; you could run a continuous thread in the background that sends ping requests and if it doesn't receive a response the main thread can be notified and a reconnect should be issued.
If you want to get messy you can work with select() to detect keep alive messages; however this may require some OS configuration depending upon your platform.
See this thread for more details: http://www.perlmonks.org/?node_id=566568
I am creating a class which communicates with remote server. Currently my device (iPhone 4) is having connectivity via wifi and local network cellular. By default it uses wifi. It works fine in both the cases.
However when I switch from wifi to cell service, it hits error delegate. I want keep communication on going even when connectivity is changed.
Is it possible? How?
Thanks,
I don't expect it is possible. Having switched networks, you've probably also switched IP addresses. Connections are defined by the IP addresses of the end points (as well as protocol and protocol-specific data such as port numbers). So, you can't maintain a connection when the IP address changes. You must cleanup and dispose of the broken connection and open a new one.
If the high-level protocol you're using, such as FTP or HTTP, allows it, you can try resuming the data transfer at the point it was interrupted. For example, if downloading a file, you may be able to resume the download at the file position of the last data you received.
Our web service has a "ping" function which is great for testing if the web service is available or not (I don't really care if the internet connection is available, right?) and I know how to test this condition, but how do I go about implementing this in my application? As in where do I test?
If there is no connection, the app doesn't crash of course, it just returns an empty table view or set of views. Should I put the ping before each request and generate an exception or error message when the ping fails? The web service request + response itself can take longer than the transmission of the actual data (latency I guess it would be) so I worry that implementing a Ping before each request might almost double the time it takes to perform each request. Or, should I be continually ping-ing and making sure there is a connection? What is the best practice?
Or should I even worry about it at all?
I was able to use the Reachability library as seen in the answer to How to check for an active Internet connection on iOS or OSX? . You can extend the library to include not only hostReachable but wsReachable with a little bit of work that is probably obvious to all.
iOS can provide you with callbacks once the network connectivity changes (e.g. from airplane mode to cell only to wifi and back). So you get notified whenever the network state changes and you don't need to keep pinging the server and can display proper online/offline messages.
Have a look at the SCNetworkReachabilitySetCallback method in the NetworkReachability.h header.
I've looked at Reachability sample from apple and another sample from "Iphone developer's cook book"
Here are steps to test ip/port reachability
construct sockaddr_in variable with given ip/port.
call SCNetworkReachabilityCreateWithAddress with the address
call SCNetworkReachabilityGetFlags and see if kSCNetworkFlagsReachable is set.
I find that whatever valid(valid-range) ip/port I put to test, my code says it's reachable even though they are not actually reachable when i ping or telnet test.
(I have seen other SO posts where reachability test to specific ip always succeed)
Reachability reachabilityWithAddress does not work
is SCNetworkReachability.. call only checks the validity of argument(ip address or hostname)? ie, do they actually send a packet(or do connect) to the given address to test reachability?
I can implement the async connect with timeout myself, but it's subtle matter how long the timeout should be not to be rejected by apple reviewers.(I am worried if it takes too long, apple reviewers might think my app is not handling network reachability at all)
Thank you
To answer your question based on the comments above, according to the SCNetworkReachability Reference
A remote host is considered reachable
when a data packet, sent by an
application into the network stack,
can leave the local device.
Reachability does not guarantee that
the data packet will actually be
received by the host.
This will not be able to check the status of your server but just make sure it can get a data packet out.
Apple wants for your app to elegantly fail if there are any network related issue, checking to see if internet is available using Reachability is the first step. If Reachability fails you can assume that you wont be able a server and alert the user immediately. The next steps are to properly handle errors returned by your server such as a 400 bad request, 404 file not found, setting a reasonable timeout, and not blocking the UI during long downloads while showing some sort of status indicator.
i need some help with socket.listen.
my max_connections is set to 1. but even after a client is connected if another client tries to connect, on the client side it says it has connected although the server does not report anything new.
my app is between one server and one client. and if any other client tries to connect while there is already a connection i want that connect to be refused.
please help with some ideas.
thank you very much.
You didn't supply any code, but the title of your post references Socket.Listen. The parameter given to Socket.Listen is not the maximum number of connections, rather it is the size of the "backlog" of incoming connections.
What that means is that when someone tries to connect, but your server hasn't Accept()ed the connection yet, those clients are in the "backlog" queue. You've set the size to 1, so only 1 client can be waiting to connect at a time.
This parameter does not have an effect on the total number of connections allowed to your application.
You can use the IsConnected property on your TCPClient to check if a connection already exists and decide upon that.
I propose you to accept new client connection but acquire the semaphor immediately before access to wrapped server and release it immediately after access. This approach allows you to control how many clients are using wrapped server concurrently.