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
Related
I am trying to establish a socket connection between an Android and a UWP application over WiFiDirect. UWP application advertise itself enabling others to discover it. Android app search for available WiFiDirect device and connect with the UWP application.
I am successful in initialising and connecting over WiFiDirect between Android and UWP. But I am confused about creating Socket connection after WiFiDirect connection is made. More specifically I am hesitant on which side should i create ServerSocket and client-socket.
In Android side i have seen example of creating ServerSocket if the device is group-owner and vice-versa. But in UWP side I am not sure which one should i create.
Android side code to create socket:-
override fun onConnectionInfoAvailable(info: WifiP2pInfo?) {
if (info!!.groupFormed && info.isGroupOwner) {
// Creating ServerSocket
}
else if (info.groupFormed) {
// Creating Client Socket
}
}
On UWP side after connection request is received my sample code:-
private async void Listener_ConnectionRequestedAsync(
WiFiDirectConnectionListener sender,
WiFiDirectConnectionRequestedEventArgs args)
{
WiFiDirectConnectionRequest request = args.GetConnectionRequest();
WiFiDirectDevice _device = await WiFiDirectDevice.FromIdAsync(request.DeviceInformation.Id);
var endPoints = _device.GetConnectionEndpointPairs();
EndpointPair firstEndpoint = endPoints[0];
// Which socket connection should i create
// StreamSocket or StreamSocketListener
}
I have tried a hack in UWP which seems to work but I am not confident about it
if (firstEndpoint.LocalHostName.CanonicalName.EndsWith("1"))
{
// creating server socket
// StreamSocketListener and waiting for incoming connection
}
else
{
//Creating client socket
// StreamSocket and connecting with remote host
}
How should i decide create socket connection type in UWP side? Please provide the fundamental concept that i am missing here.
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.
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..).
I've been running a Socket.IO server (https://github.com/mrniko/netty-socketio) , communicating with a client (https://github.com/nkzawa/socket.io-client.java) that runs on an Android emulator. The emulator is hosted on the machine that runs the server. I was able to create the initial connection from the client to the server, and successfully send a message (client to server), but shortly after that the heartbeat failed and the connection was broken:
DEBUG [07:17:45.470] c.c.socketio.transport.NamespaceClient: Client
157e4f73-e26d-459c-ac1c-506628b66a09 for namespace has been
disconnected DEBUG [07:17:45.470]
c.c.socketio.SocketIOChannelInitializer: Client with sessionId:
157e4f73-e26d-459c-ac1c-506628b66a09 disconnected DEBUG
[07:17:45.470] c.c.socketio.transport.NamespaceClient: Client
157e4f73-e26d-459c-ac1c-506628b66a09 for namespace /android/ has been
disconnected DEBUG [07:17:45.471]
c.c.socketio.handler.ClientHead: 157e4f73-e26d-459c-ac1c-506628b66a09
removed due to ping timeout DEBUG [07:17:46.119]
c.c.s.transport.WebSocketTransport: Client with was already
disconnected. Channel closed!
Server code:
Configuration serverConfig = new Configuration();
serverConfig.setHostname(MACHINE_IP);
serverConfig.setPort(8082);
serverConfig.setPingTimeout(20);
SocketIOServer server = new SocketIOServer(serverConfig);
server.addNamespace("/android/")
server.start()
Client code:
IO.Options options = new IO.Options();
options.transports = new String[]{"websocket"};
options.reconnectionAttempts = 5;
options.reconnectionDelay = 10000;
Socket socket = IO.socket(MACHINE_IP + ":8082/android/", options)
What am I doing wrong?
Thanks.
I was finally able to resolve the problem myself (there may be other solutions as well).
What I did was:
Start the server on localhost - as it isn't necessary for it to be visible outside of the machine
Connect the client to 10.0.2.2 - which is the way for the emulator to access its host localhost
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.