I have configured one xbee pro as coordinator (API mode) and other as router (API mode). I trying to send data from coordinator to router using xbee java api, but in the router code i keep getting null, am I doing something wrong.
Below is the code for Sending data (coordinator):
public class MainApp {
private static final String PORT = "/dev/ttyUSB0";
private static final int BAUDRATE = 9600;
public static void main(String[] args)
{
String data = "Helloww";
XBeeDevice mycord = new XBeeDevice(PORT, BAUDRATE);
try {
mycord.open();
System.out.println("Port is opened\n");
System.out.println("remote device connection\n");
//mac of my router
RemoteXBeeDevice router = new RemoteXBeeDevice(mycord,
new XBee64BitAddress("0013A20040DD9BDD"));
System.out.println("Sending data\n");
mycord.sendData(router, data.getBytes());
} catch (XBeeException e) {
e.printStackTrace();
mycord.close();
System.exit(1);
}
}
}
code on router side
public class RecvApp {
private static final String PORT = "/dev/ttyUSB1";
private static final int BAUDRATE = 9600;
public static void main(String[] args)
{
XBeeDevice myrouter = new XBeeDevice(PORT, BAUDRATE);
try {
myrouter.open();
System.out.println("router port opened\n");
//mac of coordinator
RemoteXBeeDevice remotecord = new RemoteXBeeDevice(myrouter, new XBee64BitAddress("0013A20040D96FE5"));
XBeeMessage msg = myrouter.readDataFrom(remotecord);
System.out.print(msg);
} catch (XBeeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
myrouter.close();
System.exit(1);
}
}
}
On the router you need to have a loop that checks for messages and prints them out. The API should have a method you can call to check for messages before calling readDataFrom() (or maybe you just ignore the null response). Sleep for a few milliseconds between each check. Right now, there isn't much opportunity for your message to come through before the program quits.
When debugging something like this, start by isolating your problem. Which side is failing, the coordinator or the router? Are you sure the XBee modules have joined to each other and are on the same network?
One test would be to run a simple terminal emulator on the serial port connected to the router, do you see any frames coming through? If you look at a hex dump of the bytes, do you see your "Helloww" message? If not, you need to get the coordinator working first before you debug your router.
Found the issue, I was not converting the message received in the correct format. Added the below lines
String content = HexUtils.prettyHexString(HexUtils.byteArrayToHexString(xbeeMessage.getData()));
System.out.println("Hex data" + "" + content + "\n");
String value = new String(xbeeMessage.getData());
System.out.print("Actual msg" + " " + value + "\n");
Works now :)
Related
On the server side, I create a room and add each SocketIoSocket into it, after that I broadcast a binary message to that room
SocketIoServer server = serverWrapper.getSocketIoServer();
SocketIoNamespace ns = server.namespace("/");
ns.on("connection", args12 -> {
SocketIoSocket socket = (SocketIoSocket) args12[0];
socket.joinRoom("ResetInterval");
socket.on("message", arg -> {
ns.broadcast("ResetInterval", "favorite-list", "Hi".getBytes(StandardCharsets.UTF_8);
})
})
Everything is okay for the first client but for the second one, I received a message said that the Packet that second client got was not binary, it was something like this:{"\_placeholder":true,"num":0} and throw error when I tried to decode it since it was in Json format. Here is my lines of code for client:
public static void main(String[] args) {
Socket socket = null;
try {
socket = IO.socket("ws://localhost:9093");
} catch (URISyntaxException e) {
e.printStackTrace();
}
socket.on("favorite-list", objects -> {
System.out.println("Receive msg: " + objects[0].toString());
});
socket.connect();
}
This was what I had for the first client
And the log what second client had:
I tried to google and even debug to find a solution but I got nothing so far
public void connect() {
final String msg = "";
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
s = new Socket("192.168.1.3", 1337);
textView.setText("Connection acquired");
out = s.getOutputStream();
output = new PrintWriter(out);
output.println(msg);
textView.setText("message sent : " + msg.length());
output.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
});
thread.start();
}
I am using the above code to connect to desired IP [192.168.1.3]... I have created another program at the other end... The problem is that the IP sometimes changes to 192.168.1.4 or 192.168.1.6... and when I use another network it changes to 192.168.43.2... now due to this I have to go every time into the code and change it manually....
Is there any function or any other thing that might search for IPs available then check if desired port exists and then connect... Thanks in advance
That's why DNS names exist. If you use an IP address, you have to use that exact address. If you use DNS, you do a name->IP lookup. Get a dynamic DNS provider and use that to give your server a name.
You really do not want to start port scanning to find open ports. You will be treated as an attacker and kicked off the network, because you really would be doing something attackers do.
I am trying to create a socket connection between a .Net server application and Java Client Application.
I am getting an error from the java client application:
Connection refused: connect
Notes:
Communicating with a .Net Client Application, works fine.
I have disables the windows firewall
Undoubtedly, I am running the server application in the background and then I am running the client application
Following are my server code (C#):
public class Server
{
public Server()
{
CreateListener();
}
public void CreateListener()
{
// Create an instance of the TcpListener class.
TcpListener tcpListener = null;
IPAddress ipAddress = Dns.GetHostEntry("localhost").AddressList[0];
string output;
try
{
// Set the listener on the local IP address
// and specify the port.
tcpListener = new TcpListener(ipAddress, 13);
tcpListener.Start();
output = "Waiting for a connection...";
}
catch (Exception e)
{
output = "Error: " + e.ToString();
MessageBox.Show(output);
}
}
}
and client application code (Java):
public class smtpClient {
public void Send() {
Socket smtpSocket = null;
DataOutputStream os = null;
DataInputStream is = null;
try {
smtpSocket = new Socket("localhost", 13); // FAILURE
os = new DataOutputStream(smtpSocket.getOutputStream());
is = new DataInputStream(smtpSocket.getInputStream());
} catch (UnknownHostException e) {
System.err.println("Don't know about host: hostname");
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
It fails at the following line in the Java Client Application:
smtpSocket = new Socket("localhost", 13);
I can't tell what is the issue you are facing, but you need to start with a solid foundation to discover these issues.
As a rule of thumb, you should always write one piece (typically the server) first and verify connectivity (say using telnet) and then write the other piece (typically client) and verify its connectivity.
I always keep a Standard Client and Server handy to test whether its my code or its the environment/configuration.
Below is a sample code that works fine to test connectivity.
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
class ClientServer {
static void Main() {
new Thread(() => { StartServer("localhost", 5013); }).Start();
Thread.Sleep(100);
Console.WriteLine("\nPress enter to start the client...");
Console.ReadLine();
StartClient("localhost", 5013);
}
public static void StartServer(string serverInterface, int port) {
try {
IPHostEntry hostInfo = Dns.GetHostEntry(serverInterface);
string hostName = hostInfo.HostName;
IPAddress ipAddress = hostInfo.AddressList[0];
var server = new TcpListener(ipAddress, port);
server.Start();
Console.WriteLine($"Waiting for a connection at {server.LocalEndpoint}");
Console.WriteLine("Press ctrl+c to exit server...");
while (true) {
TcpClient client = server.AcceptTcpClient();
Console.WriteLine($"Server says - Client connected: {client.Client.RemoteEndPoint}");
ThreadPool.QueueUserWorkItem((state) => {
using (var _client = (TcpClient)state)
using (NetworkStream stream = _client.GetStream()) {
string msg = stream.ReadAsciiData();
if (msg == "Hello!") {
stream.WriteAsciiData($"Time:{DateTime.Now: yyyy/MM/dd HH:mm zzz}. Server name is {hostName}");
}
}
}, client);
}
} catch (Exception e) {
Console.WriteLine(e);
}
}
public static void StartClient(string serverInterface, int port) {
Console.WriteLine("Client started...");
try {
using (var client = new TcpClient(serverInterface, port))
using (NetworkStream stream = client.GetStream()) {
Console.WriteLine("Client says - Hello!");
stream.Write(Encoding.ASCII.GetBytes("Hello!"));
string msg = stream.ReadAsciiData();
Console.WriteLine($"Client says - Message from server: Server#{client.Client.RemoteEndPoint}: {msg}");
}
} catch (Exception e) {
Console.WriteLine(e);
}
Console.WriteLine("Client exited");
}
}
static class Utils {
public static void WriteAsciiData(this NetworkStream stream, string data) {
stream.Write(Encoding.ASCII.GetBytes(data));
}
public static string ReadAsciiData(this NetworkStream stream) {
var buffer = new byte[1024];
int read = stream.Read(buffer, 0, buffer.Length);
return Encoding.ASCII.GetString(buffer, 0, read);
}
public static void Write(this NetworkStream stream, byte[] data) {
stream.Write(data, 0, data.Length);
}
}
Now to your specific problem,
The choice of port 13, is not ideal for testing. Usually all ports below 1024 are considered privileged. i.e. a firewall or antivirus might block your attempt to listen on that port
Remember that IPV6 addresses plays a role. Your machine might have that enabled or disabled based on your configuration. You want to make sure that if your server is listening on a IPv6 interface, then your client also connects on the same
Which brings us to another related point: Irrespective of you are using IPv6 interface or not, the client needs to connect to the same interface the server is listening on. This might seem obvious, but is often missed. A typical machine
has at-least 2 interfaces: One for localhost (127...* called loopback interface) and another non local (typically 10...* or 192...*, but not restricted to it). It can so happen (especially when you pick the first available interface to bind your server without knowing which one it is) that server might be listening on non loopback interface like say 192.168.1.10 interface and the client might be connecting to 127.0.0.1, and you can see why the client will get "connection refused" errors
The sample code above works and you can test your code with it. You can us telnet for a client or just my sample code. You can play around changing the serverInterface values to some surprising discoveries which are accentuated by
ipAddress = hostInfo.AddressList[0] line
Hope this helps you with your debugging
I am trying to connect to a bitcoin node using the ZMQ library for Java. the problem is that when I try to receive a response the code remains frozen. Returns nothing.
This is my code:
public class CBETest {
private static final String TEST_URL = "obelisk.airbitz.co";
public static void main(String[] args) {
System.out.println("\t--- ZMQ ---");
Ctx c = zmq.ZMQ.createContext();
SocketBase s = c.createSocket(zmq.ZMQ.ZMQ_DEALER);
zmq.ZMQ.connect(s, "tcp://"+TEST_URL+":9091");
System.out.println("Connected!");
int sent = zmq.ZMQ.send(s, "blockchain.fetch_last_height", 0);
System.out.println("Sent: " + sent);
Msg msg = zmq.ZMQ.recv(s, 0);
System.out.println("Response " + Arrays.toString(msg.data()));
}
}
The code freezes in the line Msg msg = zmq.ZMQ.recv(s, 0);. I am using the calls described here for the full node implemetation. Thanks in advance!
The code is not freezing, it is blocking while waiting to receive a message.
I would suggest you put your above code in a thread/runnable class and use localhost as the TEST_URL and start the server.
Then create another Runnable class with a client that tries to connect to that port and send back a message and start that thread and see if the message gets through.
There is an example here:
http://zguide.zeromq.org/java:rtdealer
It appears to me that newer Android devices run behind a NAT, where the local address is an internal carrier or LAN address and the public address is the router or carrier assigned external address.
Nevertheless, newer phones don't return the same address using the NetworkInterface as when accessing an IP detection service.
Therefore, connecting via direct P2P SocketChannels inherently fails.
Are there any common workarounds to this problem designed for the Android platform? Can anyone clarify what is causing this NAT-like security issue?
Any links to Java NAT traversal tutorials or examples (NOT essays or theses) would also be appreciated as being helpful (as I'm not quite sure how to implement it in Java).
I will of course also accept any other solutions anyone has to offer!
Almost every phone or PC you will ever touch won't have a static public IP address, and therefore will require NAT traversal. It's not because of the device; the carrier or ISP put routers between your device and the public internet. Depending on your application, usually there are NAT-traversal libraries you can use, such as ice4j or STUNT.
I do that in my own project and have found this issue is not that complicated.
Here's a very simple UDP echo server in node.js
var dgram = require('dgram');
var socket =
dgram.createSocket('udp4');
socket
.on('listening', function()
{
var address = socket.address();
console.log('socket listening ' +
address.address + ':' + address.port);
})
.on('error', function(err)
{
console.log('socket error:\n' + err.stack);
socket.close();
})
.on('message', function(message, rinfo)
{
console.log('message: ' + message + ' from ' +
rinfo.address + ':' + rinfo.port);
var msg = new Buffer(rinfo.address + ':' + rinfo.port);
socket
.send(msg, 0, msg.length,
rinfo.port, rinfo.address,
function(err, bytes)
{
//socket.close();
});
})
.bind(15000);
An android client simply send a msg to this node server
System.out.println("UDP hole punching=======================");
class IOth extends Thread {
#Override
public void run() {
String sendMsg = "UDP hole punching";
byte[] buf = sendMsg.getBytes();
DatagramPacket packet;
System.out.println(HPremoteHost); // node server IP
System.out.println(HPremotePort); // 15000
try {
packet = new DatagramPacket(buf, buf.length, InetAddress.getByName(HPremoteHost), HPremotePort);
ds.send(packet);
} catch (Exception e) {
System.out.println("error================");
System.out.println(e);
}
}
}
IOth io00 = new IOth();
io00.start();
Android Client UDP listener to obtain general msg and your own Global ip&port via UDPholepunching
class IOLoop extends Thread {
#Override
public void run() {
try {
String msg = "Native.UDPserver.open";
SocketAddress sockAddress;
String address;
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
while (true) {
try {
ds.receive(packet);
sockAddress = packet.getSocketAddress();
address = sockAddress.toString();
msg = new String(buf, 0, packet.getLength());
System.out.println(msg + " received !!! by " + address);
// this case is UDP HolePunching reaction
if (address.equals(HPaddress1)) {
System.out.println(msg + "hole punched");
// So you can obtain own Global ip& port here.
// exchange this information
// `remoteHost` `remotePort` to another client
// with some method (signaling server)
}
} catch (IOException e) {
}
}
} catch (Exception e) {
}
}
}
IOLoop io00 = new IOLoop();
io00.start();
Android Client UDP sender using other client's IP remoteHost remotePort
class IOth extends Thread {
#Override
public void run() {
String sendMsg = "This is a test message";
byte[] buf = sendMsg.getBytes();
DatagramPacket packet;
try {
packet = new DatagramPacket(buf, buf.length, InetAddress.getByName(remoteHost), remotePort);
ds.send(packet);
} catch (Exception e) {
}
}
}
IOth io00 = new IOth();
io00.start();
Look at http://sourceforge.net/projects/jnat-pmplib/
It is an implementation of NAT-PMP in java.
I've managed to establish sockets just by forwarding the sockets you're using during the connection in your router. It worked for me.
UPDATE
Find out your IP address through cmd.exe if your using Windows (ipconfig) or through a terminal session if your on Linux (ifconfig). Then connect to it through the browser and there should be a security section. Go to port forwarding and open up the ports your using when establishing you're ServerSocket and Socket. Use TCP as the protocol.
Please note that this only applies if you're trying to connect from outside your wlan.