How to make two android devices to communicate through TCP - android

We want to establish TCP/IP connection between two android devices.
For now we thought that it would be simpler if we make the connection device to device. So there is no server that is between the two phones.
Most of the time (if not always) one has no real IP address (NAT and so on). Is this a problem for creating a TCP socket?
I didn't manage to find any exact information for this. Any advice and opinion will be highly appreciated.
Thanks

Is this a problem for creating a TCP
socket?
Answer is no, it does not make it impossible (unless NAT's have an unpredictable way of mapping IP addresses). However, it is not simple to accomplish.
The short answer is you'll always need a server-like peer with a public IP address to facilitate initial communication between peers located behind NATs. The peers connect to it. A tells server it wants to TCP connect with B. Server notifies B. NAT behavior analysis is performed and if possible, A and B attempt to open TCP communications with each other by predicting the next mapping of the other NAT. If all goes fine (and usually it does) A touches base with B or vice-versa. They close the other connection attempts and communicate with the operational TCP connection. This technique is called STUN for TCP.
Now, there are more complicated reason why things can go wrong. If you want to know more, I have written a book called Practical JXTA II which available for reading online at Scribd. There is a chapter dedicated to NAT traversal.
Hope this helps.

One device behind a NAT is not a problem. The requirement is: the server must be reachable by the client.
I'm using Apache Mina to handle TCP connections. It have really made my life easier. It can be used on both client and server. Give it a try...

Well to make a TCP socket one device must be listening and the other connecting. However in a real world scenario what you describe is sort of hard.
Like if you are going to communicate over a cell network between two phones, I wouldn't be surprised if the network did not allow inbound connections to a phone like that and just sandboxed each phone's IP. So while two phones might be on the same subnet IP range, they might not be on the same physical network which just makes the whole routing problem almost impossible.
If you are in control of the network and are using Wifi and natting the IPs yourself with both devices within your network, you should be able to do this just like any other client server TCP socket.

If both nodes does't have global IPs,, and are not physically in the same network,, then its impossible to communicate over TCP without a server, unless you created a controlling server that act as a relay to tell the nodes about any changes occurring on the other side

It is possible but you can experience some problems.
First of all you have to know the public address of the host you want to contact, and if your two host are in different NATTED networks you should do it using some server (like you do in SIP telephony).
Then you have to hope that the contacted host is behind a 'good' NAT like 'full cone' or similar and not behind a 'bad' NAT like 'symmetric' that not allow incoming connection. The fact you use a TCP connection instead of UDP datagram can help you because of the three-way-handshake. In fact most NAT routers accept incoming TCP connection, but not incoming UDP packets.

Related

NAT punch-through on mobile network for p2p model?

I am writing a p2p messaging Android app, and I'm trying to solve the problem of NAT on mobile networks. I cannot currently find a way for a device to connect to another listening device on a 3G/4G network due to the carrier's NAT service.
I have heard of a few NAT punch-through methods, but a lot of those involve using some sort of centralized server as a mediator. I am trying to use a completely decentralized p2p approach to accomplish this task.
Are there any feasible ways of allowing a device on a mobile network to be publicly addressable?
Thanks!
No, it is not possible. Most of the time, subscribers with IP addresses NATed are behind NAT444 and many subscribers are anycasted ( subscribers have the same IP on their mobile phone, but nated behind a different NAT devices). And 2 anycasted suscribers cannot communicate together.
The only way left you is to open a VPN to get a real IP of Internet Public.
My suggestion would be: Do not use VPN for IPv4 ! Use VPN to get a real IPV6 to your mobile phone application, and build your p2p application over IPv6.
You are fighting with very old problem that drove IETF to build IPv6.
So, go to IPv6, and forget ipv4.
The ONLY good solution for your problem is to build your app over IPv6, and your app has to bring the ipv6 tunnel to the phone.

How does SIP work on cellular network?

I'm just confused about how SIP works but mine doesn't.
I made a simple android server which open up a server socket and listen to incoming connection on 3G/4G network. Then I made a client that connect to the server, the connection was blocked by my carrier's firewall(AT&T).
After this, I downloaded an open source VOIP app based on SIP, and register these 2 phones on SIP proxy, let them call each other, this works perfectly.
I'm just so confused about how SIP works on cellular network, SIP is a p2p protocol, SIP proxy is just for redirecting. How does these 2 phones connect to each other in VOIP session? Why is this connection not blocked by carrier? Can someone explain to me? Thank you in advance!
update: I just tried sending a UDP packet between AT&T and SPRINT network, it does not work ;(
In basic SIP the endpoints media traffic generally communicate directly between each other in a P2P fashion like you said. They do this be giving each others address/port in the SIP SDP negotiation.
In a "perfect" network world this works fine as all endpoints can talk directly between each other.
As we know, this is not the case.
In most cases, the main barrier in the IPv4 world is NAT.
The first solution people came up with is STUN. STUN will give you your "public" IP address that you are using from behind a NAT and the SIP stack will use that IP address in the SIP/SDP packets. This works as long as hole punching works.
The next solution people came up with is TURN. TURN is a UDP proxy and allows a client (e.g. a SIP client) to allocate and use a IP address/port on a private network from a public network (i.e. the internet). It should work in all cases but can put a lot of network overhead on the TURN server. It will not be as efficient as P2P connections tho. The upside of using TURN is that not both sides need to support it for it to work. So it's good when you are talking between a softphone on the internet to a hardware SIP device on a internal network.
The next solution people came up with is ICE. ICE needs to be supported on both SIP endpoints. It works by extending the SDP protocol to allow it to add all possible connections in the SDP negotiation (all local network adapters, public addresses provided by STUN and TURN allocated addresses in priority order). Then one side goes through the listed connections and tries to make a connection. This allows both connections to be "try" to connect P2P and fallback to a TURN connection if nothing else works. It should also work in any networked environment to any networked environment and find the most efficient network path between the SIP endpoints. The downside of ICE is that both SIP endpoints need to support ICE for it to work. (As a aside, ICE/TURN/STUN is now a requirement for the WEBRTC protocol for web browsers to talk between each other for the same reason)
Other possible solutions would be for you to have some sort of "smart" sip proxy in the middle that maybe fakes ICE on one side if the other side doesn't support it. Another is to have some sort of media gateway or B2BUA if transcoding is required, this would have the same problems as TURN tho.
I would suggest that you setup your SIP client with STUN, TURN and ICE if possible and that will increase the likelihood of the SIP call actually working.
As to why your case doesn't work now, it would require network and/or SIP logs to understand what the exact impediment is.

What defines a "direct communication" between 2 computers ( or a phone and a computer ) ? for UDP (or TCP ) communication?

I want to write a program to access my Android phone's camera on my laptop wirelessly, so, my phone will act like a wireless webcam.
I want to implement the UDP ( or TCP ) protocol in Java to communicate between my laptop and phone.
I was thinking of making an ad-hoc wireless network in my laptop and connecting my phone to it first, and then write the code to create a server socket on my laptop and client socket on my phone.
I know this code will work for a "direct communication" between server and client. but will this method of ad-hoc network communication count as a "direct communication" ?
If not, what do I do to achieve this ?
Thank you, firstly for reading my whole problem, and,
thanks a lot if you can answer this for me
:)
First of all: Don't concentrate on ad-hoc networks. In most cases WiFi with infrastructure mode access points will be available. If on the road, all recent versions of Android are able to act as a wireless access point.
So let's assume both devices are connected to the same network and are able to reach each other (using the IP protocol) - in other word they are able to ping each other. The next issue you have to solve is: How do both applications find each other? Bonjour/Zeroconf might be a solution (see Are there any other Java libraries for bonjour/zeroconf apart from JMDNS?).
The next question is: What protocol you want to use? You mentioned TCP and UDP. In most cases UDP will be used for transmitting video data, because you have a lower latency and the video codecs are tolerant on missing packets.
With this information you can create a ServerSocket and (from the client side) know where to connect to it.

Send data using Tcp/Udp

Here is my scenario.
I have my device (android phone).
And I know the IP address of another device (which is some remote device in the Internet)
So how do I send data to the other device?
Do I use protocols like Tcp or Udp?
EDIT : And I know there are public IP addresses and private IP addresses (like when a device connects via WiFi). In such a case is it even possible to use Tcp or Udp???
What you're looking to do is a common task with a common problem (but also with a common solution). You want to send data from one device (computer/phone/etc..) to another. Here's how it works behind the scenes:
There are a lot of computers in the world. Each computer is given an identity - a name, if you will, which is called the computer's IP address. There are many versions/standards of the IP address, and the current standard names an IP address as such: "111.222.333.444". There are only so many permutations with 12 digits of numbers - and entire ranges of IP addresses are reserved. In other words, there aren't enough IP addresses to go around for computers.
Now, routers were invented, among other reasons, to combat this problem. Routers give all computers within its local area network (LAN) one public (WAN) IP address. With an average of one router per household, this saves many IP addresses. Unfortunately, it also breaks direct communication between computers, because how does one communicate with three computers all using the same name? How does one identify computer A from computer B from computer C when they all share the same WAN IP address?
First, let's clarify that - just like there are a few versions and standards of IP addresses, so there are a few types of routers. By the way, it's not the router that is to blame for the problems of direct communication between computers - it's actually the router's underlying technology of network address translation (NAT). Anyways, there are a few types of NAT, and although information on the internet is relatively scarce on these types, you can still Wikipedia it and read a few university research papers. The types are Full Cone NAT, Restricted NAT, Port Restricted NAT, and Symmetric NAT.
So, computers in a LAN share the same WAN IP. This is a problem. What's one solution? What if we instructed the router to route all incoming traffic directed to a certain port, to a certain computer in our local area network? For example, if three LAN computers share the WAN IP of 1.1.1.1, we can setup a procedure called port forwarding to instruct the router to route all packets arriving on port 6000 to 192.168.1.101:3500.
uPnP is just a fancy technology (not always present in routers - or more importantly, hardly ever enabled by default) that allows you to port forward using code.
If we can't use uPnP to port forward because not all devices have it enabled, there must be another solution - and there is: hole punching.
Hole punching comes in two flavors: UDP and TCP, although TCP hole punching is a bit more complicated because TCP is inherently first a connection-oriented protocol. UDP hole punching is easier because you can send packets without a connection (in fact, is there really such a thing as a connection?)
You can read the procedure on UDP hole punching on Wikipedia and other sites. The concept works like this, though. Any computer sending an outbound packet will expect a reply, meaning the router will allow the inbound packet's reply. At first, two computers will not expect a reply from each other, so the first packet each computer sends will be rejected by the router. If we continue sending packets, however, the router will allow the rest of the packets to come through, because a reply is expected from each computer. As long as this hole-punched connection is maintained active by occasional keep-alive packets, it will stay alive. Unfortunately, this method of UDP hole punching is unsuccessful for Symmetric NATs (explained in the links below). That's why the end-all solution is to simply proxy the connection and traffic through your own server. This requires a farm of computers, so it's quite costly. But this end-all solution is called TURN. STUN is a web service you can query to determine your NAT type and public IP (as opposed to parsing cmyip.com). Just some terms you'll encounter along your personal research.
Playing around with these concepts help. Here are some resources to get your started:
Types of NATs: http://think-like-a-computer.com/2011/09/16/types-of-nat/
A Method for Symmetric NAT Traversal (basically by spamming a lot more packets to a lot more ports): http://www.goto.info.waseda.ac.jp/~wei/file/wei-apan-v10.pdf
Lidgren Networking Library (which has NAT traversal built-in, this is a C# library): http://code.google.com/p/lidgren-network-gen3/w/list
In most realistic cases, you send data to the other device by sending the data to an intermediate device from which the other phone picks it up. Can can use protocols like TCP or UDP directly between the two devices, and that may or may not work depending on the protocols and how the devices are getting Internet access.
For example, one device can send an email and the other device can retrieve that email. You can generalize that model to other types of communication.

Android to Android TCP Connection

All of the documentation, examples and questions I've seen so far on TCP connections with Android have been between an Android device and a computer. As unreliable as wireless can be, is it possible to make a client-server TCP connection between Android devices over WiFi, and if so, how?
Edit: I guess I should elaborate more on my situation.
My Droid does not respond to ping or accept incoming TCP requests from anything unless I first make the Droid a client and my laptop the server. After this initial connection is established I can then ping from my laptop, or make the Droid a server and my laptop the client. What I can't do is make one Droid the server and another a client, I always get a "No route to host" error.
It feels like there is something blocking incoming connections unless the device initiates a connection to something else, and even then the only request the device will accept is with this device. How can I make my Droid a server that accepts all incoming TCP requests from any device on my local intranet?
You should be able to. Just do like you would do with computer/device connections, except run the client and server code on the devices.
One of the neat things about the Internet is that the Internet doesn't care whether you are establishing a connection between two PC's, a PC and a phone, or two phones. I would look at the Socket documentation, that should be enough to get you rolling.
It's certainly possible. The only problem is figuring out the IP address. I don't expect a phone have a fixed IP... However, if there is a fixed "login" server somewhere in the Web which IP is known to both phones then they can do a handshake via that server and after that continue peer-to-peer.
re; The only problem is figuring out the IP address. I don't expect a phone have a fixed IP.
Try this;
Use the web browser on the phone to log into this website: It should provide you the IP address.
http://whatismyipaddress.com/

Categories

Resources