Is it possible to establish a TCP/IP session between two smartphones? I know that a smartphone can connect to a server, but cannot respond to connection requests.
Is there a protocol out there to somehow establish this? Its OK for a server to be involved in the initial handshake
I actually don't know any way to establish p2p connection here, but I think approach with the server in the middle should meet your expectations. it's called socket-connections, at a glance it looks like a channel, that hosts on a server side, and any clients (devices) can join this channel (two or more, whatever you want). If device send a message to the server, it should broadcast the message toward all other participants (it can broadcast the message even to the sender itself, but with some meta-information so we can distiguish our own messages and ignore them).
Thereby first of all you need server with socket connection established, then you can implement any of already existing solutions (e.g. https://github.com/daltoniam/Starscream for iOS). Also you may want to take a look at AWS https://aws.amazon.com, as it has the socket connection service out of the box for the server side and required SDK for both Android and iOS platforms.
Related
just want to know is there any methods to allow 2 different apps to communicate. Both of the apps are installed on different devices as well. I had gone throught quite a lot of research, but seem that INTENT, BROADCAST RECEIVER failed to meet my scenario. INTENT, BROADCAST RECEIVER can be work if both of the apps installed on the same device.
Here i can say you can use to make your things work :-
Sockets are typically used to accomplish this between Android devices (or between any peer devices).
When two devices desire to interact, you configure one or both of them to "listen" for connections on a socket and accept a connection from the other when that happens (or you can have a dedicated client and server and the client always initiates the connections).
You can exchange messages after the link has been made.
Android client server socket applications come in a variety of forms, but one that I found handy was:
Example of Android Server/Client using Socket on the client side (and its companion server side blog article - link included in the client blog)
It should be noted that you might need to add your own "protocol" on top of this. For instance, if you are sending a file that is unknown in length without a special "end" character, you might want to add a byte (or several bytes to represent an int, long, etc.) at the beginning to indicate the length of the transmission so the receiving side can tell when it has received everything (or that it has not received everything in case of an error).
connecting via networks (such as most 3G/4G) that forbid inbound connections
Even though there is nothing theoretically blocking sockets from functioning in these situations, many mobile operators will not permit inbound socket connections in practise. You would also need to determine the mobile's public IP address, which is doable but adds complexity. Whether your solution will only ever operate on a single operator's network, you can test it out to see if it works; but, if it doesn't, you could discover that using a server in the "middle" is preferable and easier: Devices A and B establish connections with servers Device A "discovers" device B after requesting the addresses of connected devices from the server. Device A sends device B a message.
Actually, it indicates that the messages should be forwarded to device B while sending them to the server. Device B is informed by the server that a message is available for it (using some sort of message notification like Google Cloud Messaging for example, or simply by the devices polling regularly to see if they have any messages). Device B accesses the server and downloads the messages. The aforementioned will function on pretty much any network that permits internet connectivity. It does have the drawback of having a server, but for the majority of mobile networks, it is probably a necessary approach.
You make one app a server using ServerSocket.
You make the other app a client using a Socket.
With both devices in the same network the client can connect to the server knowing its local ip.
After connection established they can communicate.
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.
Before ask my question, I want to let you know what stage I am on. I have already implemented TCP/IP socket on my android app, it works fine(so far...).The connection between client(my android app) side and server side is short connection which is when a user submit information, a new thread will be created to send the message out, on the server side, once the server got the message, the server will respond "RCVD", after that the socket will be closed and then the connection is closed. My app has a lot of interactions between user side and server side, therefore it does many connect and disconnect between clients and server, so I always worry about the socket communications will drain phone battery and the performance will be affected.
Recently I find OkHttp on github and a lot of people suggest using it. Im not quite familiar with Http, only knows it is a higher level network protocol.
Can anyone tell me which way is better? which is more efficient for exchanging data(Object/Json/String) and media(Images)? Which is more faster and which use less battery?
Many thanks.
Basically, the comparison between Http and tcp socket is meaningless, But in your situation it really matters.
As you described, in your tcp socket way, you may create new connection each time receiving new push from server, which is not that efficient, If you use OkHttp, when your client exchange message with the same server, the same tcp socket is reused each time rather than make a new one.
By the way, As for the push service, use XMPP(over tcp) may be better cause Http is not optimized for such short message exchange model(You should use some extra strategy on the server side to keep the connection from being closed), but you may have to handle some implements about XMPP server and client.
Most of you are aware that iOS and Android use push notifications to inform the phone of any arbitrary event. I am interested in how one would implement such a server-initiated notification system. As the clients most probable use NAT, the server can't open a new TCP connection to them.
As far as I can see, the phone only has TCP and UDP connectivity. TCP uses keepalive to terminate the connection on the server after some idle time. Although keepalive can be disabled completely, that would expose the server to all sorts of DoS attacks by creating lots of connection contexts.
So I think there is some kind of timeout involved after which the phone re-establishes the connection. Additionally, if using TCP connection with disabled keepalive, how are changing IP addresses on the phone handled? Or does the phone establish a new connection periodically? What are the used timers?
Hope somebody knows a bit more about it.
UPDATE to clearify: I do not want to use iOS or Android Libraries (APNS or GCMS). I want to know how Google/Apple implemented it on the lower OSI Transport- and Networklayer (APNS and GCMS are Application layer or at least above Transportlayer). This is a very TCP specific question, that has nothing todo with iOs or Android programming.
I'm in the early stages of writing an app that will need to broadcast data to several other devices.
My first thought was using an UDP broadcast, however according to both
http://code.google.com/p/boxeeremote/wiki/AndroidUDP and
Android 3G UDP Broadcast
he UDP will not be able to push through the NAT when on the mobile network
(which is essential for my app).
I know that i could either use a server to broadcast however i'd rather avoid generating to much traffic on my home server.
The last alternative that i can think of is having several tcp/ip connections and looping through all connected clients and sending the broadcast. But since I'm counting on having at least 30 listeners I believe this will be to expensive.
I do not have any broadcast associated code yet, that's why I haven't posted any;)
Is there a way to break through the NAT? Will the phone be able to handle 30 simultaneous tcp/ip connections? Or should i look into some other method of broadcasting?
Any hint would be greatly appreciated!
Kind regards
Johan Risch
:::::::::::::::::::::::::ADDED::::::::::::::::::::::::::::::::
I will be sending strings of length 10-20 characters once every 30-360 seconds
(will be controllable by the user) containing geo points in string format. The order in which the data will be sent is not important, that's why I thought of udp first.
I've set up my server so that when a user logs in he/she updates my database with his/her current ip.
Preferably i'd like it to work globally, but as long as it would work within the mobile networks in the same country.
That's about all the relevant information i can think of, hope this clears some things up!
:::::::::::::::::::::::::/ADDED:::::::::::::::::::::::::::::::::
The NAT doesn't pass UDP through because UDP has no destination address, so technically UDP has to be sent to all subnetworks of the network. When the network is your home LAN, it's no big deal, but when the network is your ISP or university backbone or cellular provider, the UDP could be replicated to hundreds of thousands of subnets. That's a packet storm that will degrade network performance for everyone, and it's massive overkill for your particular app since you really only want to talk to a small number of clients.
This problem has been solved many times already. Instant Messaging clients have a similar situation as yours: want to do direct P2P messaging when possible, through firewalls. How do they do it? The original NAT traversal / firewall traversal solution was to set up a message relay server. All clients talk to the server, and the server echos messages from one client to the others as appropriate. It works with NATs and firewalls because the client initiates the outgoing connection to the server.
If the clients are able to establish a peer to peer connection, then the relay server can just give the clients each other's IP addresses and stop relaying messages.
UPNP is a protocol that enables clients to request a firewall to open a port for incoming traffic. BitTorrent clients use UPNP to enable clients to connect P2P for file sharing. Clients find each other via the torrent server. Most home LAN firewall routers support UPNP now, but it seems doubtful to me that a cellular network provider would provide UPNP support for over the air connections.
Another (remote) possibility is multicast TCP/IP, but as I recall this is really optimized for "push" content flowing from the server to clients rather than client-originated peer to peer.
Your best bet is to take a look at the open source IM clients out there, particularly ones with Android implementations, and see how they're doing IM. Jabber is one that comes to mind, I'm sure there are others. You could even use an IM system's messaging API as your data transport layer and more or less stay out of the wire level details completely.