Reachability Class always returns Reachable - reachability

I'm using the Reachability class from apples demo projects to ping some servers pages. But no matter what I write in URL I always get ReachableViaWiFi.
Reachability* reachability = [Reachability reachabilityWithHostName:URL];
NetworkStatus netStatus = [reachability currentReachabilityStatus];
I'm connected to a Wifi, but I just want to check if some servers are available or not. (With the answer "NO" if I'm disconnected from the net).
Any suggestions please, even with others classes with the same goal.
Thanks

From the docs:
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.
Edit: So, if there is a route available (whether the server is actually listening or not), it return that route's quality, in your case WiFi.
How about just sending your request and checking out the result?
As to your question for another library: Those questions are deemed off topic here.

Related

ESP32 can't recieve multicast UDP Packet

I am trying to let two or more ESP32-S2s communicate from one to the others over udp. Since they possibly dont know each others ip i wanted to use multicast.
Sending MulticastPackets is working.(At least I can wireshark the Packets on my PC).
Recieving on the other esp doesnt work so far.
Im Broadcasting to 192.168.178.255:7777
The reciever uses the following code:
//Called once after Wifi is connected:
udp.beginMulticast(OAL_Broadcast, OALPort); // 192.168.178.255, 7777 as inputs
//Called periodically :
Serial.println(udp.parsePacket()); // In my case always returns 0
What am I missing?
A few things could be happening.
The multicast IP address range is between 224.0.0.0-239.255.255.255 and usually a device joins a multicast group on one of those. Also it might treat sending a multicast more loosely when it comes to the IP address but receiving one it must be within the range of multicast addresses due to how it routes that packet to a multicast group.
If one device is on another network device but still on the same network then it could be ttl related and each network device is treated as a hop. I have seen something like this happen before. You might be able to adjust that on the network device side or on the esp32 side.

How to get handle on addr of client which lost connection?

I have a UDP server implemented using the template in the documentation, which can be found here: https://docs.python.org/3/library/asyncio-protocol.html#udp-echo-server-protocol
I would like to know the addr of the client which lost connection. The connection_lost callback only has a single parameter, exc for the exception.
Edit: Following the downvotes I want to highlight that its not a very noob-friendly part of the module naming a callback in the datagram ServerProtocol class 'connection_made'.
The Python API designers need to document this properly.
It looks like connection_made() is called when you create the socket and connect it, which in turn only happens if you specify a non-None Remote_addr.
To understand all that, first you need to understand what connect() does to a UDP socket at the Berkeley Sockets API level:
It conditions the socket so that write() andsend()can be used as well assendto()`, both of which will only send to the connected target address.
It conditions the socket to filter out all datagrams that did not originate at the connect target.
It does not create a wire connection of any kind. Nothing is received by the peer or sent on the wire in any way.
You can connect() a UDP socket multiple times, either to a different address or to null, which completely undoes (1) and (2).
So, I can only imagine that the connection_lost() callback is called when (4) happens, which it isn't in your code.
Whatever it does, if anything, it certainly can't be used to detect when a client disconnects, as there is no such event in UDP.

webRTC to setup signaling server

how to setup a signaling server for webRTC when the system are connected in Local Area Network? Its mandatory that we must use STUN and TURN server for signaling?
To make WebRTC run on LAN, you will require to have a signaling server in that LAN. A signaling server is any web server that will allow your web clients to exchange the SDP offer/answer and ICE candidates that are generated by the WebRTC PeerConnection. This can be done using AJAX or WebSockets.
I have listed some top sources for information about WebRTC. Please go through some of the links on that page to better understand how the WebRTC signaling works.
You will not require a STUN/TURN server as your WebRTC clients (i.e. Web Browser) will be in the LAN and accessible to each other. FYI... STUN/TURN servers are not part of the signaling but part of the media leg and usually required for NAT traversals of media.
Webrtc needs some kind of signalling system for initial negotiation.. like transferring SDP, ICE-candidates, sending and receiving offers etc... rest is done by peer-peer connection. For initial signalling you can use any technique like sending AJAX calls, using socket.io etc.
STUN and TURN servers are required for NAT traversal, NAT traversal is important because it is needed for determining the path between peers. You can use google provided STUN/TURN server address stun:stun.l.google.com:19302 etc , or you can configure your own turn server by using rfc-5766 turn server
Making signalling server for WebRTC is quite easy.
I used PHP, MYSQL and AJAX to maintain signalling data.
Suppose A wants to call B.
Then A creates offer using createOffer method. This method returns an offer object.
You have to transfer this offer object to user B, This is a part of signalling process.
Now create MYSQL database, having columns :
caller, callee, offer, answer, callerICE and calleeICE
Now offer created by A is stored in offer attribute with the help of AJAX call .
(Remember to use JSON.stringify the JS object before "POSTing" object to server.)
Now user B scans this offer attribute created by caller A , again with the help of AJAX call.
In this way , offer object created at user A can arrive at user B.
Now, user B responds to the offer by calling createAnswer method. This method returns answer object. This can again be stored in "answer" attribute of database.
Then the caller A scans this "answer" attribute created by callee B.
In this way, answer object created by B can arrive at A.
To store iceCandidate object representing caller A, use "callerIce" attribute of MYSQL table. Note that, callee B is scanning "callerIce" to know the details of caller A.
In this way we can transfer the iceCandidate objects representing future peer.
After you complete transferring of iceCandidate object, the connectionState property holds "connected" indicating two peers are connected.
If any questions, let me know!
Cheers ! You can now share local media stream to the remote peer.

How to send request from server to client using GKSession?

I want to know how can I send request from server to client using GKSession?
The reference class for GKSession say the following:
- (void)connectToPeer:(NSString *)peerID withTimeout:(NSTimeInterval)timeout Parameters peerID The string that
identifies the peer to connect to.
timeout The amount of time to wait before canceling the connection
attempt.
Discussion
When your application is acting as a client, it calls this method to
connect to an available peer it discovered. When your application
calls this method, a request is transmitted to the remote peer, who
chooses whether to accept or reject the connection request.
What should I use if I am server?
As a server you make yourself available for client connections with
peer2peerSession.available = YES;
Here is an example of creating a GKSession instance as a server:
[[GKSession alloc] initWithSessionID:sessionID displayName:#"Chris" sessionMode : GKSessionModeServer];
Here is an example of how to create a GKSession as a client:
[[GKSession alloc] initWithSessionID:sessionID displayName:#"Angel" sessionMode : GKSessionModeClient];
GKSessionModePeer will create a GKSession instance that will both advertise itself as a server, and at the same time look for advertising servers (in other words act as a client searching for servers).
You then need to set a delegate for your GKSession object, after-which the delegate needs to implement the following delegate method:
- (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState : (GKPeerConnectionState)state
Within the above method you will receive messages from the session that a device has become available, became unavailable, connected, etc.
To send a request:
[_session connectToPeer:peerID withTimeout:_session.disconnectTimeout];
To accept a request:
[_session acceptConnectionFromPeer:peerID error:&error];
There is a lot of code involved and the best tutorial for you to understand everything is located here: Simple Card Playing game using GKSession

iOS Packet Length

I am writing a small app that essentially swaps XML back and forth a-la SOAP. I have an OS X-based server and an iPad client. I use KissXML on the client and the built-in XML parser on the server. I use GCDAsyncSocket on both to communicate.
When I test my app on the iPad simulator, the full XML comes through. Everything works fine.
However, when I use my development device (an actual physical iPad), everything else works fine, but the XML terminates after the 1426th character. I have verified that this error occurs on multiple iPads.
When I subscribe to the incoming packets on GCDAsyncSocket I use
[sock readDataWithTimeout:-1
buffer:[NSMutableData new]
bufferOffset:0
maxLength:0
tag:0]; and previously just a simple [sock readDataWithTimeout:-1 tag:0]; but both have the same result. It seems that GCDAsyncSocket is not to blame at any rate since the execution is fine on the simulator. Note that the 0 at maxLength indicates an 'infinite' buffer.
Does anyone have any idea what could be causing this?
1426 sounds very much like the MTU (Maximum Transmit Unit), which is the size of the maximum TCP data you can send. It's different sizes on different network media and different configurations, but 1426 is pretty common.
This suggests that you're confusing the reception of a TCP packet with the completion of an XML message. There is no guarantee that TCP packets will end on an XML message boundary. GCDAsyncSocket is a low-level library that talks TCP, not XML.
As you get each packet, it's your responsibility to concatenate it onto an NSMutableData and then to decide when you have enough to process it. If your protocol closes the connection after every message, then you can read until the connection is closed. If not, then you will have to deal with the fact that a given packet might even include some of the next message. You'll have to parse the data sufficiently to decide where the boundaries are.
BTW, it is very possible that your Mac has a different MTU than your iPad, which is why you may be seeing different behavior on the different platforms.
The solution was that when left unspecified, AsyncSocket looks to the next line-return. When the packet terminates, it indeed returns the line. I was using (sock is my GCDAsyncSocket object)
[sock readDatawithTimeout:-1 tag:0]
but have since moved to
[sock readDataToData:[msgTerm dataUsingEncoding:NSUTF8StringEncoding]
withTimeout:-1
tag:0]
where msgTerm is an external constant NSString defined as "\r\n\r\n" and is shared between the client and server source. This effectively circumvents the line return issue ending the packet.
One additional note regarding this solution: Because I am using a SOAP-like protocol, the whitespace is not an issue. However if yours is temperamental about terminating whitespace lines you can use a method like [incomingDecodedNsstringMessage stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] to clean it up.
Having had a look at the code for GCDAsyncSocket, I'd say it is entirely possible there is a bug in it. For instance, if you are reading a secure socket, the cfsocket mechanism is used instead of ordinary Unix style file descriptors, on iPhone and the author may be making invalid assumptions about when a socket is closed. Since you have the source code, I'd try stepping through it with a debugger to see if end of file is being flagged prematurely.
TCP is a stream based protocol. Theoretically, the packet size of the underlying IP protocol should make no difference, but if you read the socket fast enough, you may well get your data in chunks the size of the IP packet especially if the IP stack is somehow tuned for memory use (guessing here!).