I'm doing an application that will comunicate with a TCP server. I based my work on the following example http://myandroidsolutions.funcode.ro/2013/03/31/android-tcp-connection-enhanced/.
Right now I'm looking how to verify if there is a connection between Client and Server. The mBufferOut.checkError() only give an error after 2/3 tries. I need to know if my message was sent or not.
Thank you
In network communications, you are never sure when (or if) the remote party received the message in full, in part, or at all.
If the connection is broken, then you know for certain that message was not received in full.
But if you need a timely confirmation, the server should send some confirmation message. Your application protocol needs to support this, though.
The same is valid to know if the connection is "up" or "down": TCP does not exchange any packets when idle, unless you activate keep-alive (which is not normally recommended). It may well happen that the party thinks it has a connection, only to send a message and then it fails (perhaps because a router was reset while the connection was idle).
To solve the problem we need to look at the return value of readLine(). If it return null so our tcp connection was closed.
Related
As shown above, I have a socket server (in UDP) running on my Raspberry Pi. I also have a socket client running on my Android app.
Currently, the app client always initiates communication and the RasPi always responds.
The RasPi can even initiate communication and send socket packet to anyone if it knows the IP address.
The problem is my app has to wait for a Thread to receive data forever (basically polling). Like below:
uniSocket.receive(receivePacket);
Should both RasPi and Android run clients and servers or is there something like Datagram_Socket_Callback or some asynchronous method to receive and send data.
The receive call will block until there is something to receive. That isn't polling; it's just waiting. It could wait in the receive call for days at a time if there's no notification to be sent. And that occupies no more resources than a server threading running on the android side (waiting for a connection) would occupy.
You probably will need some kind of periodic keep-alive to ensure the other side hasn't disappeared. You can do that yourself at the application layer, or TCP provides a keep-alive mechanism you can activate with setsockopt for this purpose.
In other words, create a socket, enable TCP keep-alives, send an "I'm waiting for notifications" message to the server, and then call receive to wait. The server then maintains a list of client connections waiting for notifications, and can then send data through a connection whenever there is something to be sent.
For your normal client-server communications, you could use the same socket, but it might be more complicated to synchronize that way, so alternatively, you could just create another socket in parallel.
I don't know a lot about android/app development but obviously your client will need to be prepared to re-create the connection if it's broken. I can think of many reasons why that might happen in normal usage. For example, the initial connection might be created from an IP address obtained on your home network. Then you walk out of your house and lose that IP address. You may now need to recreate the connection with a different IP address on the cell network (or the wifi at the coffee shop or whatever). If the phone goes into Airplane mode, you might lose all IP addresses for a time.
I'm sure it's possible to create a server that runs in android as well, but then you have the problem of the RPi needing to know the android's IP address which may change frequently. I would say it's better to keep the client role on the android side.
Hi I am developing android application in which I want show whether other person is online or not so that person can intiate the communication.I thought about few solution :
1) Implementing heartbeat mechanism, in which device will send ping request to server after fix interval of time.
2) Server will send push type ping to client and client will give response on that so that server will know that client is online.
First case causes battery and data issue, while second one causes delay in push which will affect the process.
Is there any better solution for this problem? Apart from these or improvise version of above one.
nilkash. Virtually any method for checking network connectivity will at the end result in sending periodical pings between device and the server. Even push type ping will actually do the same (but it saves battery because push notifications aggregate messages for all applications in-to a single connection to a google server). So the best solution is just a proper combination of optimizations and you have to choose them depending on your requests.
Server pushes are power efficient, mostly because they reuse the
same connection for all applications, but the delay can be huge,
something like 10 minutes.
You can subscribe to connectivity
events and send "online" message to server once you are online. (But
not once you are offline because you are... offline). This will give
you immediate online events.
Do not send pings from device when there is no connectivity. Your application should be absolutely idle so as not to use battery.
There is no easy way to find out
when client goes offline on server side. You have to trade
traffic/battery for time resolution. More often you send pings, the
better resolution is. But you can't change ping interval for pushes,
so if you need better resolution, then you need to use your own
connection. But you can send other useful data through that connection too.
If you keep a TCP connection, then your pings can be
very data efficient: TCP keep alive packets are just 60/54 bytes.
But then you have to keep open connections with all clients on the
server. This may be a problem if you have a lot of clients.
The best combination may be something like that: you always send online message from a client when it becomes online. You keep TCP connection while the application is in foreground. You use the same connection to transfer data to and from the application. When your application goes to background you fallback to power consuming push based pings and do them at 10 minutes basis.
I'm working for an App Android and I need my phone was always connected to my server MQTT...
But my phone can lost his connection(Tel :[FIN;ACK]; Serv:[FIN;ACK];Tel:[ACK]); after that, when he send a [SYN] message for connect it to the server MQTT, the serveur send an [RST,ACK]... And this while the service of my app is in activity.
In my case , i MUST to re-launch my server if i want my phone can be reconnect, but, i can't reboot my server (multi-phone possible, and i need real-time performence).
There is there a possibility to connect my phone without reboot my server?
Thank's for time.
Best regard
Guillaume
I think your problem is similar to the one I had. The connection was half closed. See http://www.codeproject.com/Articles/37490/Detection-of-Half-Open-Dropped-TCP-IP-Socket-Conne for details.
The way I solved this was to i) add keep alive msgs, every 5 secs. from the phone to the server and ii) have the server close the connection if there was no incomming data for 15sec. See http://www.forward.com.au/pfod/CheapWifiShield/index.html and www.pfod.com.au
MQTT includes keepAlives (PING request msgs) so you only need to modify your client to specify a short keepAlive interval
see http://www.hivemq.com/blog/mqtt-essentials-part-10-alive-client-take-over
to have the MQTT server to more quickly close the connection once it stops getting your data or keepAlive msgs.
Although the above link states
"The broker will close the previous connection to the same client (determined by the same client identifier) and establishes the connection with the newly connected client. This behavior makes sure that half-open connection won’t stand in the way of a new connection establishment of the same client."
So you should not be having this problem at all !!!
I am working on Android project which communicates over TCP/IP. Communication works on specific protocol - this protocol is message oriented.
android device sends message to server via socket
server sends answer message to android device
It is not problem but I have a few parlous questions.
I don't have any idea how to solve connection interrupts (wifi, edge, change wifi to edge over open socket, ...) and connection timeouts? If android device sends 1 message and in this moment are connection problems - then android device sends different message (other request) - it is guaranteed that answers will be delivered in correct sequence?
I tried set timeout for socket object but it didn't work. I dont know why but if I set timeout to 5 seconds and I turned off the server before I sent message - it took more than 5 second before she came exciption.
I didn't found any articles on internet about this problems.
Thank you very much.
For TCP sockets the way you can get timeouts is by using select() or poll(),in Android you have to use SocketChannel() (java.nio) class to deal with non-blocking sockets. They both can query a socket for a specific period (10 or 20 seconds for example) and can tell you if it is writeable (you can use send()) or readable (there is data to be read recv()). Also the select() command will tell you if the socket has an error, most probably a broken connection. When you get such an error (except an interrupted signal, this one should be ignored and reissue the select), all you can do is close the socket and reopen a new one with the server, there is no way, as far as I know, to recover a broken connection, although, if you've implemented in the protocol, you can resume where you left off when the socket was broken. I don't know how you've implemented the protocol, but most of them will required a positive ACK (acknowledge) from the receiver before going on with another message. Also, when establishing a connection the client should specified if it a brand new connection or a broken one and act accordingly.
The idea is:
The sender sends a header specifying the command to process and the length of the data it's going to send after the header, the receiver receives the header and the data, once it process it, it sends a response ACK packet to the sender with a positive value to acknowledge the message, optionally with some data in case it's necessary. If after a reasonable period of time you don't receive the ACK packet then you may resend the same data again until you receive the positive ACK.
There could be the situation where the client sends a message, the server receives it and processes it, but when the server sends the positive ACK packet the connections breaks and the client never receives the packet, so it will resend the same message again once the connections is reestablished. To avoid this situation, it's necessary to send a message ID (an int which increments for every message sent) in the header to identity it.
I know it sounds difficult and it's in fact. If the connection is on the same network (intranet) it works nicely but, when the communication is on the internet, you may face a lot of problems and situations which you can't control, so it's necessary a well defined protocol where you can recover from broken connections and the transactions/messages won't be duplicated.
I'm trying to develop a turn base game over XMPP. ( The only solution I found for multiplatform game ). I can send messages without problems. If the other user isn't online, the server (OpenFire) save it for later deliver.
The problem cames when a device change the network ( change from 3g to WiFi, change 3g IP... ) or the device lost the network ( turn off 3g, wifi or lost connection ). The server thinks that the device is online and send the message but it ( obviusly ) never arrive, so packet is lost.
I know one solution. Implement ACK over my game protocol, but I don't like this idea to much. Do you have any other suggestion? I think this is a server problem. Do you know another server witch implements TCP or ACK?
Thank you!!
EDIT: I do that: Connect device to server. I turn down the 3G and WiFi connectivity to the device. Android and the server still thinking that the connection is alive.
http://issues.igniterealtime.org/browse/SMACK-331
PD: I ask to openfeint for they multiplayer api, but they didn't asnwer me...
Although BOSH will likely work in this case, another option is XEP-0198: Stream Management. This will allow you to have all of the performance of a fully-connected socket, along with quick reconnects, positive acking, and queuing while un-acked or disconnected in both directions.
Under some conditions TCP/IP is not reliable. This is why ACKs, message receipts, IQs or other extensions in XMPP can solve this problem.
I have done lots of mobile programming over the years, also often with Openfire. But I have not seen lost messages. So I assume that there is a problem in either the library you are using on Android, or the Openfire version you use.
Instead of using raw sockets you can also use BOSH:
http://xmpp.org/extensions/xep-0124.html
BOSH is based on WebRequests like Comet and works very well in environments where you switch or loose often the connection. It can keep the connection alive until your network is back and does not result in connection drops when one or more requests fail in a row.
I too came across this issue and been trying to figure out a proper way to get this resolved.
Problem for me is that I set the offline messages policy to "Always Store" and thus XEP-0184 doesn't really help out to determine if a message is not getting delivered to its receiver.
Providing this scenario:
- I have 2 users chatting, call them A and B
- A sends B a message while B's connection just got lost
- The message got dropped and A is not notified
- In this case A does not know that the message got dropped, it'll just assume that the message is delivered to the server, server will eventually deliver it to B
- B lose the message forever
So I temporarily put in a work around for this... i store all those messages that are not delivered (i.e. haven't receive the message delivery receipt) into a queue, then periodically (say, 6 minutes - it's the time when those dead connections got wiped) check every message of the queue to see if the intended recipient is "Online" AND the receipt's still not received... If it's the case, then I mark that message as "Failed delivery"
This is quite a terrible way to fix it (please advise if you have a better way of doing it). I think the best thing to do is to have the server to do this: if message failed to deliver and the offline message policy is "Always Store", then we store it to "ofoffline" for delayed delivery.
This is an old one, but I was solving such an issue recently. It helped me when I set the XMPP resource (the last part of full JID) to something reasonable, when building connection. Otherwise it will be random generated on each reconnect - and that changes the full JID.