I am new in Android networking and working on project p2p without server.
Initially I have to do communication between 2 devices. I achieved successful communication between two wifi networks within and behind different NATS via DataGramSocket with port forwarding via Upnp using library.
The problem i am facing is while communication between Mobile network and my wifi network or between 2 mobile network. When i send message from mobile network I am unable to receive it in my app but can listen on same port in NetCat app.
Anyone can help me in this regard?
Sending
try {
socket = new DatagramSocket(dstPort);
address = InetAddress.getByName(dstAddress);
socket.connect(address,dstPort);
socket.setBroadcast(false);
socket.setReuseAddress(true);
//sendState("Socket Status "+socket.isConnected());
String sendString = msg;
byte[] sendData = sendString.getBytes("UTF-8");
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length,
address, dstPort);
socket.send(sendPacket);
//sendState("Sent = "+sendData);
} catch (SocketException e) {
//sendState(e.getLocalizedMessage());
sendState("SocketException");
}
Receiving
try {
socket = new DatagramSocket(dstPort);
address = InetAddress.getByName(dstAddress);
// send request
byte[] buf = new byte[4096];
DatagramPacket packet =
new DatagramPacket(buf, buf.length, address, dstPort);
socket.connect(address,dstPort);
socket.setBroadcast(false);
socket.setReuseAddress(true);
socket.receive(packet);
String line = new String(packet.getData(), 0, packet.getLength());
sendState(line);
//sendState("Reached3");
} catch (SocketException e) {
//sendState(e.getLocalizedMessage());
sendState("SocketException");
}
Port Forwarding via UpNp
protected void setUpnp(int port_)
{
if(Connectivity.isConnectedWifi(this)) {
String myIp = getIpAddress();
int port = port_;
//creates a port mapping configuration with the external/internal port, an internal host IP, the protocol and an optional description
PortMapping[] desiredMapping = new PortMapping[2];
desiredMapping[0] = new PortMapping(port, myIp, PortMapping.Protocol.TCP);
desiredMapping[1] = new PortMapping(port, myIp, PortMapping.Protocol.UDP);
//starting the UPnP service
UpnpService upnpService = new UpnpServiceImpl(new AndroidUpnpServiceConfiguration());
RegistryListener registryListener = new PortMappingListener(desiredMapping);
upnpService.getRegistry().addListener(registryListener);
upnpService.getControlPoint().search();
}
else if(Connectivity.isConnectedMobile(this))
{
}
}
While the code here seems fine there are a couple problems with your approach.
Most mobile networks do not support UPnP port forwarding.
Depending on your network topology (which you can't always control) there might be two or more layers of NAT routing behind your public-facing address. The closest layer might support UPnP, but other layers might not.
Instead of UPnP, you might want to try the UDP hole punching technique for NAT traversal explained here and here.
While it requires a publicly available server to coordinate 'peer introduction', this technique is far more widely supported (92-96% of peers) in today's highly fragmented internet than other techniques such as UPnP port forwarding, particularly when dealing with mobile networks or multiple layers of NAT routing.
It basically boils down to UDP being a connectionless protocol (unlike TCP), so when two peers (behind NAT routers) send a UDP message to each other simultaneously, their respective NAT routers are 'tricked' into believing the inbound request from the other peer is a response to the original outgoing packet.
Besides, if you are concerned about the cost of running a server, these days you can get many years of free cloud VM server usage if you rotate membership among the main cloud vendors (AWS, Microsoft, Google, AliCloud..).
Related
I need to calculate the total bandwidth retrieving a webpage takes through Tor in android. In my android app, I create a Tor circuit using the Tor library and retrieves the webpage and then close the Tor circuit. How can I get the total bandwidth (Tor circuit creation + request sent + response received)?
Is it possible to calculate the total bandwidth theoretically, if we know the bandwidth without Tor?
int port = onionProxyManager.getIPv4LocalHostSocksPort();
int proxyPort = port;
String proxyHost = "127.0.0.1";
String remoteHost = "google.com";
int remotePort = 80;
Socks5Proxy socks5Proxy = new Socks5Proxy(proxyHost, proxyPort);
socks5Proxy.resolveAddrLocally(false);
Socket socket = new SocksSocket(socks5Proxy, remoteHost, remotePort);
BufferedReader dIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintStream dOut = new PrintStream(socket.getOutputStream());
String str = null;
do {
str = dIn.readLine();
response = response + str;
} while (str != null);
onionProxyManager.stop();
Tried Network profiler as suggested by JensV below. I couldn't find total data usage using the network profiler. Is there anything I'm missing? I have added the screenshot below.
I don't think this will be possible. I'm assuming that you're using this library (inferred from your code). I looked at the source of the library and to create tor proxy, it actually spawns a separate process which launches the tor binary.
So while technically somehow possible, the library offers no way of intercepting/inspecting the packets (or packet size) itself.
If you just want to do inspections, you can use the Network Profiler in Android Studio. There you should be able to see how much traffic is being done. You could also collect data this way and approximate how much overhead you have from basic network requests and show an estimate to the user.
You could create a wifi hotspot on your laptop and connect to it via the android phone. From the laptop, you install wireshark to analyze the TOR traffic. If you type in google "setup wifi hotspot Ubuntu", you find a lot of example to set this up. And the same for Wireshark and tor traffic.
I have created an Android application that has two input fields and a verify button. I want to send information to a SQL Express server that is on my Windows desktop over UDP connection. I have tested the connection with a utility and it works perfect but when I connect to the server, I don't know where the default location is for the information to be stored. Can anyone please help me? Below is the UDP connection code.
int port = 48569;
try {
DatagramSocket s = new DatagramSocket();
InetAddress local = InetAddress.getByName("10.3.22.218");
int msg_length = msg.length();
byte[] message = msg.getBytes();
DatagramPacket p = new DatagramPacket(message, msg_length, local, port);
s.send(p);
}catch (SocketException e) {
e.printStackTrace();
}catch (UnknownHostException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}
SQL Server on your desktop does not listen for UDP packets. Information sent with these packages will not be stored anywhere. To connect to SQL Server you will need a client (ADO.NET). Sending packages over the wire will not work. And why UDP? How you will get back the result from the "verification"?
And I believe connecting directly from your mobile app to the SQL Server is not the best option. You should either create some service layer over your database (for example WCF service) and use this API from your mobile app, or go further and look for Azure Mobile App Service or something similar.
what is the best approach of connecting android to server and ip and corresponding port? THis connection doesn't need to be all the time, but I am assuming I will send and recive files (in byte arrays or streams).
Thanks
Since the Android Development Tools are native to Java, you can use simple Java Socket APIs to accomplish this goal (see ServerSocket and Socket).
Server Code
You must start by opening a ServerSocket on your host computer by defining a port to listen on:
ServerSocket ss = new ServerSocket([some_port]);
Then you must begin listening for a client by calling ss.accept(). This method will block until a client connects:
Socket my_socket = ss.accept();
You now have a socket on your server that you can manipulate as you wish (probably through the use of ObjectInputStream and ObjectOutputStream):
ObjectOutputStream out = new ObjectOutputStream(my_socket.getOutputStream());
ObjectInputStream in= new ObjectInputStream(my_socket.getInputStream());
Client Code
You must establish a connection with the server that you have just created. You will do this by initializing a socket and passing in the IP address of your server (usually localhost for most testing purposes) and the port number on which your server is currently listening:
Socket socket = new Socket("localhost", [some_port]);
Again, establish some streams for communication:
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
And there you have it! You can now easily communicate with a server from an Android device. It is much simpler than you would think.
Please note, however, that this architecture implements TCP, which is much slower than UDP and will not work for any type of fast-paced data intensive games, but should accomplish your goals given your description above.
I am trying to implement a simple Android application that sends and recieves packets to and from a plugin written for Openfire server. The plugin is meant to recieve packets from a client for further processing. So it is not a chat. The following code snippet shows my way of sending packets to the server:
ConnectionConfiguration configuration = new ConnectionConfiguration(
HOST, PORT);
Connection connection = new XMPPConnection(configuration);
try {
connection.connect();
} catch (XMPPException e) {
e.printStackTrace();
}
if (connection.isConnected()) {
Packet packet = new Message();
packet.setFrom("123456789#localhost");
packet.setTo("987654321#component.localhost");
connection.sendPacket(packet);
connection.disconnect();
}
HOST and PORT are predefined constants.
I tried to use code in if clause inside the plugin and it worked perfectlly - component recieves packets and works with them. However, in my Android application this code does not work - packets do not reach the component.
So, guys, if you have any suggestions I will be greatful for your help. Maybe I use wrong technique somewhere - I am new to XMPP and Openfire.
Update
There are all needed permissions in application's manifest. And HOST is equal to a static IP address of the PC running Openfire server.
private static final String HOST = "192.168.1.100";
private static final int PORT = 5222;
In order to send packets to a server you should login to it using login() or loginAnonymously() methods of org.jivesoftware.smack.Connection class.
Thanks mr. Flow for the hint.
Connect and Disconnect
// Create the configuration for this new connection
ConnectionConfiguration config = new ConnectionConfiguration("jabber.org", 5222);
config.setCompressionEnabled(true);
config.setSASLAuthenticationEnabled(true);
Connection connection = new XMPPConnection(config);
// Connect to the server
connection.connect();
// Log into the server
connection.login("username", "password", "SomeResource");
....
// Disconnect from the server
connection.disconnect();
</code>
you should login first, here is the guide to manage connections http://www.igniterealtime.org/builds/smack/docs/latest/documentation/connections.html
in my app i want to receive some message form the server and based on that i want to display pop up message and for this i want to do socket communication in android.
When i am try to read response form the server using socket.getInputstream i will get error
"request time out :Address family not supported by the protocol"
Here is my code.
Socket socket = new Socket("localhost",62000));
boolean isconnect = socket.isConnected();
Log.e("Socket Connection ", String.valueOf(isconnect));
// Read and display the response message sent by server application
//
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
String message = (String) ois.readObject();
System.out.println("Message: " + message);
ois.close();
socket.close();
Unfortunately, this exception is caught and reported by Android, and your app doesn't get to see the stacktrace as far as I know (and it's reported at the debug level).
I'm pretty sure the cause of this exception is that an outside machine is trying to access Android and the port is closed (so the connection is refused).
Make sure:
You have a server running on the right port in Android
You turn on port forwarding for that port (e.g. you can have the service running on port 10000 in the Android emulator, and have your computer's port 20000 forward to that port)
Your client is accessing Android using 0.0.0.0 via the forwarded port (20000, not 10000)
You correctly specify TCP or UDP (might break things if it's the wrong one)
Hope this helps!