udp in android example - java

i am using the below code to send text message between two android devices but i could not receive the packet at the receiver side
the sender:
String messageStr="Hello Android!";
Log.d("note","message prepaered");
int server_port = 12345;
try{
Log.d("note","socket prepaered");
DatagramSocket s = new DatagramSocket();
Log.d("note","socket defined");
InetAddress local = InetAddress.getByName(ip.getText().toString());
int msg_length=messageStr.length();
byte[] message = messageStr.getBytes();
Log.d("note","converting message to bytes");
DatagramPacket p = new DatagramPacket(message, msg_length,local,server_port);
s.send(p);
Log.d("note","sending msg");}
catch (SocketException e){
Log.d("error",e.getMessage());
}
catch(IOException v1){
Log.d("error", v1.getMessage());
}
the receiver :
String text;
int server_port = 12345;
byte[] message = new byte[1500];
try{
DatagramPacket p = new DatagramPacket(message, message.length);
Log.d("note","putting msg in packet");
DatagramSocket s = new DatagramSocket(server_port);
Log.d("note","defining socket");
s.receive(p);
Log.d("note","recieving packet");
text = new String(message, 0, p.getLength());
msg.setText(text);
s.close();
}
catch (SocketException e){
Log.d("error",e.getMessage());
}
catch(IOException v1){
Log.d("error", v1.getMessage());
}
thanks in advance for help

Ok. There are a lot of undefined variables in your story.
First of all, you should try this at a local machine, where you can be sure that this is not a network problem.
Second, try to wrap the receiving code in a endless loop, it will make the debugging easier.
If by now, you found out that your code is actually working on a localhost,
you should check your network configuration on your devices, make sure you are using the right addresses, and both devices are in the same network.
If you have trouble making your code work on a localhost, try to test your server and client independently on a working software, like http://sourceforge.net/projects/sockettest/ for example, it will allow you to make sure that your client and server code is working
Also don't forget about the timing, start your receiver first.
P.S. Please format your code properly.

Related

Java Sending a short String via Socket in a high frequency

I am trying to make an application to control DMX Channels. For this I have an ESP8266 which takes a String as an input like "2.255", where the first integer is the DMX Channel and the second integer the value.
For my PC I wrote a method that first builds the string and then sens it to the IP Address of the ESP8266 via a Socket.
for(DMXChannel c : list){
if(lastvalue.get(c.getChannelID() - 1) != c.getValue()){
try {
String msg = c.getChannelID() + "." + c.getValue();;
DatagramSocket clientSocket = new DatagramSocket();
InetAddress ipaddr = InetAddress.getByName(ip); //IP Address is "192.168.4.1"
byte[] sendData = new byte[1024];
sendData = msg.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, ipaddr, 8888);
clientSocket.send(sendPacket);
clientSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
This works fine but I have a problem when I am trying to do a fade. The frequency of this piece of code seems to be too slow.
Does anyone have a "faster" solution?
Here are some things you could do to speed up the code:
Do not call getByName for an IP address. This involves DNS, but DNS is not needed for an IP address. Instead call getByAddress. If you do need to call getByName, call it only once and cache the answer.
Do not open, close, reopen, etc. the socket each time. Just keep it open.

UDP Sending and Receiving

I've looking into multiple ways to do this and nothing has helped/worked new to Java UDP packets.
My code for Android is started via a service and it runs on a new thread.
Code for waiting:
try {
int port = 58452;
// Create a socket to listen on the port.
DatagramSocket dsocket = new DatagramSocket(port);
// Create a buffer to read datagrams into. If a
// packet is larger than this buffer, the
// excess will simply be discarded!
byte[] buffer = new byte[2048];
// Create a packet to receive data into the buffer
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
// Now loop forever, waiting to receive packets and printing them.
while (true) {
// Wait to receive a datagram
dsocket.receive(packet);
// Convert the contents to a string, and display them
String msg = new String(buffer, 0, packet.getLength());
System.out.println(packet.getAddress().getHostName() + ": "
+ msg);
// Reset the length of the packet before reusing it.
packet.setLength(buffer.length);
}
} catch (Exception e) {
System.err.println(e);
}
Code for sending:
try {
String host = "MY PHONES IP";
int port = 58452; //Random Port
byte[] message = "LAWL,LAWL,LAWL".getBytes();
// Get the internet address of the specified host
InetAddress address = InetAddress.getByName(host);
// Initialize a datagram packet with data and address
DatagramPacket packet = new DatagramPacket(message, message.length,
address, port);
// Create a datagram socket, send the packet through it, close it.
DatagramSocket dsocket = new DatagramSocket();
dsocket.send(packet);
dsocket.close();
System.out.println("Sent");
} catch (Exception e) {
System.err.println(e);
}
}
It sends fine but won't receive on Android. Please help!
Also my Logcat output: http://pastebin.com/Rfw5mSKV
Thanks
-Fusion
http://systembash.com/content/a-simple-java-udp-server-and-udp-client/
I used that to and it works! Thanks to /u/TarkLark or Reddit!

Cannot bind Address already in use

This is my udp_broadcast server code where iam listening on 0.0.0.0
try{
socket = new DatagramSocket (7777,InetAddress.getByName("0.0.0.0"));
socket.setBroadcast(true);
while(true)
{
System.out.println(getClass().getName()+"ready recieve broadcast packets!");
//recieve a packet
byte[] recvBuf = new byte[15000];
DatagramPacket packet = new DatagramPacket(recvBuf,recvBuf.length);
socket.receive(packet);
System.out.println(getClass().getName() +"packet recieved from :" +packet.getAddress().getHostAddress());
System.out.println("data is "+new String(packet.getData()));
String message = new String(packet.getData()).trim();
if(message.equals("p2p_project_node"))
{
byte [] senddata = "I_found_you_did_YOU".getBytes();
DatagramPacket sendpacket= new DatagramPacket(senddata,senddata.length,packet.getAddress(),packet.getPort());
socket.send(sendpacket);
System.out.println("packet sent to "+sendpacket.getAddress().getHostAddress());
}
}
}
on client side iam broadcasting packet 255.255.255.255 so that i get a reply from server
eventually and i endup in getting server ip address
udp_client_side code
try {
c = new DatagramSocket();
c.setBroadcast(true);
byte [] sendData = "p2p_project_node".getBytes();
//this is broadcasting to 255.255.255.255a
try{
DatagramPacket sendPacket = new DatagramPacket(sendData,sendData.length,InetAddress.getByName("255.255.255.255"),7777);
c.send(sendPacket);
System.out.println("rewuest sent to 255.255.255.255");
}
catch(Exception e) {
System.out.println("exception 255.255" +e);
}
on the server side iam getting error saying that
Exception java.net.BindException "Address already in use :cannot bind"
where am i going wrong if someone could help me it would be great Thanks in advance
The address is already in use. You cannot bind your socket to that address. Some other process already has a UDP socket bound to that poet. Possibly a previous instance of your own program.
Don't broadcast to 255.255.255.255. It was deprecated twenty years ago. Use the subnet broadcast address, or better still use multicast.
You can bind your socket to that port, if this port is occupied by a previous instance of your own program. You need to use "reuse" parameter in all instances of your program. Call .setReuseAddress(true); before binding.

Multicasting message from Android app to local server

I'm developing an Android app that at some points, sends a multicast message. I'm running this on an emulator device so far.
On the same machine, I have a server (not Android, a plain Java app) that is expecting the multicast message, but it never gets it. When I start the server, since it is on my local machine, I start it the loopback interface (127.0.0.1). I must say that I've done this with regular Java apps and it works perfectly.
Here's the code for the Android App:
try {
InetAddress group = InetAddress.getByName(MULTICAST_HOST);
byte[] data = DISCOVER_MESSAGE.getBytes();
DatagramSocket ds = new DatagramSocket();
ds.setSoTimeout(60000);
DatagramPacket dp = new DatagramPacket(data, data.length, group, TcpipSIBDiscoverer.PORT);
ds.send(dp);
byte[] buf = new byte[1024];
dp = new DatagramPacket(buf, buf.length);
ds.receive(dp);
if (dp.getLength() > 0) {
byte[] tmp = new byte[dp.getLength()];
System.arraycopy(dp.getData(), 0, tmp, 0, tmp.length);
String received = new String(tmp);
Logger.debug(this, "Received from SIB: " + received);
SIBDescriptor sibDescriptor = createSIBDescriptor(received);
this.discoveryListener.connectorSIBDiscovered(sibDescriptor);
}
} catch (SocketTimeoutException e) {
Logger.error("Socket time excedeed while waiting a response when discovering SIBs. Trying again");
} catch (IOException e) {
Logger.error("There was some kind of IO error while waiting for a response when discovering SIBs. Trying again");
}
As you can see, I'm using a regular DatagramSocket instead of MulticastSocket. This works in plain Java apps, since the listening server address is 235.0.0.1:5555.
Not really sure if the code is not working or I have to do something in the emulator device so it can truly reach my loopback interface... Any ideas?
Thanks!
Alex
127.0.0.1 on android refers to the device's localhost (or the emulators).
To reach localhost of your 'local machine' you should use 10.0.2.2.
This is discussed in a lot of topics.

Unable to send data from C# to Java (Android) program

I am trying to send data from a C#.NET (Windows Application) program to a Java (Android App) program and vice versa, via TCP connection through Wifi. Till now I am success to send data from Java to C#, but unable to do so from C# to Java.
Following is the Java code, I used to create a connection and receive data:
ServerSocket serverSocket = null;
DataInputStream socketInputStream;
while (true) {
try {
String localIPAddr = getLocalIPAddress();
InetSocketAddress ipEndPoint = new InetSocketAddress(
InetAddress.getByName(localIPAddr), 8222);
serverSocket = new ServerSocket();
serverSocket.bind(ipEndPoint, 4);
workerSocket = serverSocket.accept();
socketInputStream = new DataInputStream(
workerSocket.getInputStream());
inputText.setText(socketInputStream.readUTF());
} catch (Exception ex) {
throw ex;
}
}
Here getLocalIPAddress() method returns the IP Address of the Android Device.
Following is the C# code in Windows Application to connect to the Android's IP Address (192.168.1.6) and send data to it:
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
void button1_Click(object sender, EventArgs e)
{
try
{
if (!clientSocket.Connected)
clientSocket.Connect(IPAddress.Parse("192.168.1.6"), 8222);
clientSocket.Send(Encoding.UTF8.GetBytes(txtInput.Text));
}
catch (Exception ex)
{
throw ex;
}
}
Well, client (C#) is failing to connect to the server (Java) That means data is not leaving from client. But it will, if it get connected. Please tell me what am I missing and where am I mistaken. :)
After you have launched your android app and it is connected to the wifi, did you try to do a ping to the ip where the application is launched.
ping 192.168.1.6
If the IP is accessible from the workstation where C# app is running, try to perform a telnet on the IP and Port of the android ip, to see whether it works or not.
telnet 192.168.1.6 8222
If either of the two steps fail then could be a problem in the wifi network. As i have noticed many times the firewall of the routers filters out all the ports except 8080 and 80. So you would need to open the ports on the router.
Did you try to do this?
Runnable showmessage = new Runnable() {
public void run() {
myTextView.setText(membervariabletext);
}
};
and from your thread, after the readUTF(), call
runOnUiThread(showmessage);
Found this here
Well, I have solved this myself, but of course Dilberted has helped me a little bit. I thank him for what he has provided. :)
Check out the solved Java code below:
ServerSocket serverSocket = null;
Socket workerSocket;
DataInputStream socketInputStream;
try {
if (serverSocket == null) {
// No need to get local IP address and to bind InetSocketAddress.
// Following single line make it very simple.
serverSocket = new ServerSocket(8222, 4);
workerSocket = serverSocket.accept();
}
// When data are accepted socketInputStream will be invoked.
socketInputStream = new DataInputStream(
workerSocket.getInputStream());
/* Since data are accepted as byte, all of them will be collected in the
following byte array which initialised with accepted data length. */
byte[] rvdMsgByte = new byte[socketInputStream.available()];
// Collecting data into byte array
for (int i = 0; i < rvdMsgByte.length; i++)
rvdMsgByte[i] = socketInputStream.readByte();
// Converting collected data in byte array into String.
String rvdMsgTxt = new String(rvdMsgByte);
// Setting String to the text view.
receivedMsg.setText(rvdMsgTxt);
} catch (Exception ex) {
throw ex;
}
Note that a separate thread is to be used to run this code in background.

Categories