Im trying to Send out a DatagramPacket on a MulticastSocket. This bit is working but when i try and get the info out of the header its not working.
while(true){
byte[] packet = new byte[1500];
DatagramPacket packetR = new DatagramPacket(packet, packet.length);
socketM.receive(packetR);
ByteBuffer data = ByteBuffer.wrap(packetR.getData());
byte[] senderAddress = new byte[100];
byte[] senderCommand =new byte[100];
data.get(senderAddress,0,4);
InetAddress senderIP = InetAddress.getByAddress(senderAddress);
data.position(4);
data.get(senderCommand,0,1);
String command = (char)senderCommand[0]+"";
System.out.print(senderIP+": "+ command+"\n");
}
This works but i just get all of it printed out
while(true){
byte[] packet = new byte[100];
DatagramPacket packetR = new DatagramPacket(packet, packet.length);
socketM.receive(packetR);
InetAddress ip = packetR.getAddress();
String meg = new String(packetR.getData());
System.out.print(ip+": "+ meg+"\n");
}
Can anyone see why this would not work thanks.
The fourth byte of data is given by packet.getData()[3].
If that doesn't answer as clarified in your comments you will have to clarify further.
Related
I have written a simple Client/Server code in Java, in which a client sends a message to server (which is displayed on Server's Standard Output) and then server also sends a message (which is displayed on Client's Standard Output). Code for Client and Server is given below:
Client.java
import java.io.*;
import java.net.*;
public class Client {
public static void main(String[] args)throws Exception {
DatagramSocket socket = new DatagramSocket ();
InetAddress address = InetAddress.getByName("127.0.0.1");
DatagramPacket packet = null;
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
byte[] buf = new byte[256];
String msg = stdIn.readLine();
packet = new DatagramPacket(buf, buf.length, address, 4445);
socket.send(packet);
// get response
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
// display response
String received = new String(packet.getData(), 0, packet.getLength());
System.out.println("Server says: " + received);
socket.close();
}
}
And below is Server.java
import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args)throws Exception {
DatagramSocket socket = new DatagramSocket(4445);
byte[] buf = new byte[256];
// receive client's message
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
// display client's message
String received = new String(packet.getData(), 0, packet.getLength());
System.out.println("Client says: " + received);
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String msg = stdIn.readLine();
buf = msg.getBytes();
// send the response to the client at "address" and "port"
InetAddress address = packet.getAddress();
int port = packet.getPort();
packet = new DatagramPacket(buf, buf.length, address, port);
socket.send(packet);
}
}
The code compiles and runs successfully, but the output does not come as expected. The message sent by Client is NOT displayed at Server, but Server's message is successfully displayed at Client.
So can anyone kindly tell what can be the problem?
You never populate the packet with any useful data:
byte[] buf = new byte[256];
String msg = stdIn.readLine();
packet = new DatagramPacket(buf, buf.length, address, 4445);
socket.send(packet);
You've just posted a byte array with 256 bytes, all of which are 0. You've ignored msg entirely. Perhaps you wanted:
String msg = stdIn.readLine();
byte[] buf = msg.getBytes(StandardCharsets.UTF_8);
packet = new DatagramPacket(buf, buf.length, address, 4445);
socket.send(packet);
That's similar to the code you're using in the server, after all... except that I'm using UTF-8 explicitly, which I would recommend you do everywhere, when converting between byte[] and String.
i have made a video conferencing application in java. It is based on UDP as it should be. It works well on LAN. Now I am switching it to WAN. After a lot of reading about problems in UDP transmission behind NAT (as there will be users behind different routers). I tried to implement hole punching as read. But its not working. I am using a client-server-client architecture. More precisely, every client sends its images(or frames) to server, which then forwards them to other clients. For this i am using the client's IP and port assigned to them by the router. The server then sends the packets to clients. But the packets are still blocked by the router. Can anyone tell me what should be a reliable solution to this? Or there is any library to achieve hole punching efficiently?
==================================================================================
client code:
//some code
final Socket client = new Socket(IPaddr, port); // tcp connection
...
// code for some gui components...
...
String message2="video";
clientSocketReceiver = new DatagramSocket();
String ip = "x.x.x.x";
InetAddress IPAddress = InetAddress.getByName(ip);
ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
baos1.write(message2.getBytes());
baos1.write('\n');
baos1.flush();
byte[] message2InByte = baos1.toByteArray();
baos1.close();
clientSocketReceiver.send(new DatagramPacket(message2InByte, message2InByte.length, IPAddress, 8876));
...
//some code....
...
//thread for receiving images..
while (true) {
byte[] receiveData = new byte[50000];
DatagramPacket receivePacket = new DatagramPacket(receiveData,receiveData.length);
clientSocketReceiver.receive(receivePacket);
InputStream in = new ByteArrayInputStream(receivePacket.getData());
buffImage = ImageIO.read(in);
...
//code for displaying images on GUI
...
}
//==========================================================================
=========================================================================== =
server code:
//code for storing client's ip and port. runs only when a new client is accepted by tcp socket....
serverSocket=new DatagramSocket(8876); //declared at starting of code
while (checked==false ) {
DatagramPacket receivePacket = new DatagramPacket(receiveData,receiveData.length);
serverSocket.receive(receivePacket);
String data = new String(receivePacket.getData());
data = data.trim();
if (data.equals("video")) {
vx.add(receivePacket.getAddress().getHostAddress()); // storing ip
String tmp = "" + receivePacket.getPort();
vv.add(tmp); //storing port. vv and vx r vectors
checked=true;
}
}
======================================
//thread for receiving/sending images from/to clients
DatagramSocket serverSocket2 = new DatagramSocket(9876);
byte[] receiveData = new byte[50000];
while (true) {
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket2.receive(receivePacket);
InputStream in = new ByteArrayInputStream(receivePacket.getData());
bImage = ImageIO.read(in);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bImaget, "jpg", baos);
baos.flush();
byte[] imageInByte = baos.toByteArray();
baos.close();
for (int i = 0; i < vx.size() && i < vv.size(); i++) {
serverSocket2.send(new DatagramPacket(imageInByte, imageInByte.length, InetAddress.getByName(vx.elementAt(i).toString()), Integer.parseInt(vv.elementAt(i).toString())));
}
}
=============================================
I am trying to send DatagramPackets (UDP) in my Android application:
//create a byte to receive data
mClientSocket = new DatagramSocket();
byte[] receiveData = new byte[MAX_RECEIVE_DATA_SIZE_BYTES];
DatagramPacket receivePacket = new DatagramPacket(receiveData,
receiveData.length);
// Set a receive timeout
mClientSocket.setSoTimeout(timeout);
// receive the packet
mClientSocket.receive(receivePacket);
return new String(receivePacket.getData(), 0,
receivePacket.getLength());
I get the following error:
Try again
Am I missing something here?
Well to send the UDP you'd need something similar to:
Server:
String messageStr="Hello Android!";
int server_port = 12345;
DatagramSocket s = new DatagramSocket ();
InetAddress local = InetAddress .getByName("192.168.1.102");
int msg_length=messageStr.length();
byte[] message = messageStr.getBytes();
DatagramPacket p = new DatagramPacket (message, msg_length,local,server_port);
s.send(p);
Client:
String text;
int server_port = 12345;
byte[] message = new byte[1500];
DatagramPacket p = new DatagramPacket (message, message.length);
DatagramSocket s = new DatagramSocket (server_port);
s.receive(p);
text = new String (message, 0, p.getLength());
Log.d("Udp tutorial","message:" + text);
s.close();
References:
Simple UDP communication example
I try to send a integer array via datagram socket. What is the best way to accomplish this.
MY sending code is:
public void sendObj(Object obj) {
try{
byteArr = new ByteArrayOutputStream();
objOut = new ObjectOutputStream(byteArr);
objOut.writeObject(obj);
byte[] b = byteArr.toByteArray();
DatagramPacket dgram = new DatagramPacket(b, b.length, InetAddress.getByName("230.0.0.1"), 4446); // multicast
socket.send(dgram);
System.out.println("Package is sent!");
}catch(Exception e){
System.out.println(e.getMessage());
e.printStackTrace();
}
}
And receiving code is:
byte[] b = new byte[65535];
ByteArrayInputStream b_in = new ByteArrayInputStream(b);
DatagramPacket dgram = new DatagramPacket(b, b.length);
socket.receive(dgram); // blocks
ObjectInputStream o_in = new ObjectInputStream(b_in);
Object o = o_in.readObject();
dgram.setLength(b.length); // must reset length field!
b_in.reset(); //
However when I receive it gives StreamException for unknown header value 00000
We solved that problem by a basic changes. We used a string like "100200300..." to symbolize the array by separating element with two 0' so in that way we did not use ArrayList.
You have to use getbyte() method to get the bytes and the put these bytes into a datagram packet instance and then pass it to the client or send it...
Use
arrayName.getBytes(); /// save this into some byte[] temp = new byte[size];
and make a datagram packet and put its argumnets and send it
I'm implementing a client/server application using UDP transmissions. Here is my part of my code :
Client :
InetAddress serverAddress = ...
int serverPort = ...
DatagramSocket socket = new DatagramSocket(9999);
...
String message = "<HELLO>";
byte[] outbuffer = new byte[1000];
outbuffer = message.getBytes();
DatagramPacket packet = new DatagramPacket(outbuffer, outbuffer.length, serverAddress, serverPort);
socket.send(this.packet);
Server :
DatagramSocket serverSocket = new DatagramSocket(9876);
...
byte[] inbuffer = new byte[1000];
DatagramPacket packet = new DatagramPacket(inbuffer, inbuffer.length);
serverSocket.receive(packet);
String response = new String(packet.getData(), 0, packet.getLength());
System.out.println(response);
if("<HELLO>".equals(response)){
System.out.println("OK");
} else {
System.out.println("ERROR");
}
My problem is the following: if I print the response String on the client side that is comming from the client, everything looks fine ("").
But for some reasons when I trie to compare the response coming from the server using .equals or a RegExp it fails !
May be it's related to String encoding but I don't know where and why it fails. Both client and server are running on the same host right now, so it might not be related to JVM differences.
You're currently using the platform default encoding to both encode and decode strings. You should absolutely not do that. Specify the encoding both in the getBytes() call and the constructor call, e.g.
byte[] outBuffer = message.getBytes("UTF-8");
Also note that your current code creates a byte array of length 1000 and then immediately throws it away:
byte[] outbuffer = new byte[1000];
// Byte array created on previous line is now useless!
outbuffer = message.getBytes();
... don't do that.
We can't really tell much more from the code you've given us - if you could produce short but complete programs demonstrating the problem, that would really help.
For debugging, I would suggest you log the contents of the datagram packet you receive, while still in binary. Presumably it's not what you expected, but that doesn't help to show what it was.
EDIT: Here's a pair of short but complete programs which do work:
import java.net.*;
public class Server {
public static void main(String[] args) throws Exception{
DatagramSocket socket = new DatagramSocket(9999);
byte[] inbuffer = new byte[1000];
DatagramPacket packet = new DatagramPacket(inbuffer, inbuffer.length);
socket.receive(packet);
String response = new String(packet.getData(), 0,
packet.getLength(), "UTF-8");
System.out.println(response);
if("<HELLO>".equals(response)){
System.out.println("OK");
} else {
System.out.println("ERROR");
}
}
}
// Client.java
import java.net.*;
public class Client {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket();
byte[] output = "<HELLO>".getBytes("UTF-8");
DatagramPacket packet = new DatagramPacket(output, output.length,
InetAddress.getLocalHost(),
9999);
socket.send(packet);
}
}
You have a variable response and reponse.
I am assuming that they won't be the same and your test should fail.
This is the sort of thing you should be able to see in a debugger.