I'm trying to communicate two java programs, no problem with this. Program A send a message with the word "token" and Program B receive the message and print it. The problem I have is I would like to send before length of message to Program B to create the array with the accurate length but i don't know how can i do it.
public class ProgramA {
public static void main(String[] args) {
try {
DatagramSocket datagramSocket = new DatagramSocket();
String message = "token";
InetAddress addr = InetAddress.getByName("localhost");
DatagramPacket datagram = new DatagramPacket(message.getBytes(),message.getBytes().length, addr, 5556);
datagramSocket.send(datagram);
datagramSocket.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
public class ProgramB {
public static void main(String[] args) {
try {
InetSocketAddress addr = new InetSocketAddress("localhost", 5556);
DatagramSocket datagramSocket = new DatagramSocket(addr);
byte[] message = new byte[5];
DatagramPacket datagram = new DatagramPacket(message, message.length);
datagramSocket.receive(datagram);
datagramSocket.close();
for(int i = 0; i < message.length; i++) {
System.out.print((char)message[i]);
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
If you know that the length of the message is maximum X bytes, you could use something like this:
package experiment;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class ProgramA {
public static void main(String[] args) {
try {
System.out.println("Started");
DatagramSocket datagramSocket = new DatagramSocket();
String message = "tokenasdfasdfasdfasdf";
InetAddress addr = InetAddress.getByName("localhost");
DatagramPacket datagramLength = new DatagramPacket(new byte[]{(byte)message.length()}, 1, addr, 5556);
DatagramPacket datagram = new DatagramPacket(message.getBytes(),message.getBytes().length, addr, 5556);
datagramSocket.send(datagramLength);
datagramSocket.send(datagram);
datagramSocket.close();
System.out.println("Done");
}
catch (IOException e) {
e.printStackTrace();
}
}
}
package experiment;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
public class ProgramB {
public static void main(String[] args) {
try {
InetSocketAddress addr = new InetSocketAddress("localhost", 5556);
DatagramSocket datagramSocket = new DatagramSocket(addr);
byte[] messageLength = new byte[1];
DatagramPacket datagramLength = new DatagramPacket(messageLength, 1);
datagramSocket.receive(datagramLength);
byte[] message = new byte[(int)messageLength[0]];
DatagramPacket datagram = new DatagramPacket(message, message.length);
datagramSocket.receive(datagram);
datagramSocket.close();
for(int i = 0; i < message.length; i++) {
System.out.print((char)message[i]);
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
This works assumed the length of the message does not exceed 127; otherwise your datagramPacket with the lenght of the message has to contain more than one byte
Related
I made a client-server program that works well on the same machine but I cannot get it to run on different laptops.
I checked the ports and the multicast address and everything matches.
This is my client:
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
public class BroadcastClient {
public InetAddress address;
public byte[] buffer;
public DatagramPacket packet;
public String str, str2;
public MulticastSocket socket;
public BroadcastClient() throws Exception{
socket = new MulticastSocket(1502);
System.out.println("Waiting for messages from server");
transmit();
}
public void transmit(){
try{
//receive data using port
address = InetAddress.getByName("233.0.0.1");
//register client to the group multicast
socket.joinGroup(address);
while (true){
buffer = new byte[256];
packet = new DatagramPacket(buffer, buffer.length);
//receive data from server
socket.receive(packet);
str = new String(packet.getData());
System.out.println("Received message: " + str);
}
}catch (Exception e){
System.out.println("error: " + e);
}finally {
try {
//remove client from multicast group
socket.leaveGroup(address);
//close socket
socket.close();
}catch (Exception e){
System.out.println("Error: "+ e);
}
}
}
}
And this is my server:
import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.Inet4Address;
import java.net.InetAddress;
public class BroadcastServer {
BufferedReader in = null;
String str = null;
byte[] buffer;
DatagramPacket packet;
InetAddress address;
int port;
DatagramSocket socket;
public BroadcastServer() throws IOException {
System.out.println("Sending message");
//create to receive
socket = new DatagramSocket();
transmit();
}
public void transmit() {
try {
in = new BufferedReader(new InputStreamReader(System.in));
while (true) {
System.out.println("Send to everyone");
str = in.readLine();
buffer = str.getBytes();
address = InetAddress.getByName("233.0.0.1");
//send data to port 1502
packet = new DatagramPacket(buffer, buffer.length, address, 1502);
//send messages to all clients
socket.send(packet);
}
} catch (Exception e) {
System.out.println("Error 2: " + e);
} finally {
try {
in.close();
} catch (Exception e) {
System.out.println("Error3: " + e);
}
}
}
}
This is how I call them:
Client:
public class UDPClient {
public static void main(String[] args) throws Exception {
BroadcastClient client = new BroadcastClient();
}
}
Server:
public class UDPServer {
public static void main(String[] arg) throws Exception {
//start
BroadcastServer server = new BroadcastServer();
}
}
Am I missing something? I cannot figure it out at all. The router could be my problem?
1) I am able to input and send my file name from my client to my server. but once it reaches my server I am unable to access the file even though the location and name of the file is correct.
2) since I am limited to 1500 bytes per transmission, I have to send my data in small 1500 byte packets. but I am facing problems sending data with more than 1500 bytes. this could also be because I am using a byte array.
3) I am unable to convert the mp3 file that I have read and converted to bytes back to an mp3 file
I have tried using other files to see if I made a mistake, but no matter what kind of file I use the result is always the same.
import java.io.*;
import java.net.*;
import java.util.*;
class UDPClientThreads {
public static void main(String args[]) throws Exception
{
String ul;
Scanner cin = new Scanner(System.in);
System.out.print("Enter uname: ");
ul = cin.nextLine();
long tstart = System.currentTimeMillis();
DatagramSocket clientSocket=new DatagramSocket();
InetAddress IPAddress=InetAddress.getByName("localhost");
byte[] sendData=new byte[1500];
byte[] receiveData=new byte[1500];
System.out.println("sent: "+ul);
sendData=ul.getBytes();
DatagramPacket sendPacket=
new DatagramPacket(sendData, sendData.length,IPAddress, 12313);
clientSocket.send(sendPacket);
DatagramPacket receivePacket=
new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
System.out.println(receivePacket.getData().length);
clientSocket.close();
}
}
import java.io.*;
import java.net.*;
import java.util.*;
import java.nio.file.Files;
public class UDPServerThreads {
public class UDPClientHandler1 implements Runnable {
byte[] bytesFromFile;
InetAddress address;
int port;
public UDPClientHandler1(byte[] bytesFromFile, InetAddress address, int port) {
this.bytesFromFile=bytesFromFile;
this.address=address;
this.port=port;
}
public void run() {
byte[] sendData=new byte[1500];
try{
String threadName =
Thread.currentThread().getName();
String message="in HandleClient";
long cstarttime = System.currentTimeMillis();
System.out.println("before csocket");
DatagramSocket csocket=new DatagramSocket();
sendData= bytesFromFile;
DatagramPacket sendPacket=
new DatagramPacket(sendData, sendData.length, address, port);
csocket.send(sendPacket);
System.out.println("after send in thread "+"IPAddress="+address+" port="+port);
long cendtime = System.currentTimeMillis();
System.out.println("time="+(cendtime-cstarttime));
}
catch (IOException e) {}
}
}
public void nonStatic(byte[] bytesFromFile, InetAddress address, int port) {
Thread t = new Thread(new UDPClientHandler1(bytesFromFile,address,port));
t.start();
}
public static void main(String args[]) throws Exception
{
UDPServerThreads udpserver= new UDPServerThreads();
try {
DatagramSocket serverSocket=new DatagramSocket(12313);
byte[] receiveData=new byte[1500];
int count=0;
while(true)
{
DatagramPacket receivePacket=
new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
System.out.println("after rcv in server");
String udpmessage=new String(receivePacket.getData());
System.out.println("sentence"+udpmessage);
try
{
File f = new File(udpmessage);
byte[] bytesFromFile = Files.readAllBytes(f.toPath());
System.out.println(bytesFromFile.length);
InetAddress address=receivePacket.getAddress();
int port=receivePacket.getPort();
udpserver.nonStatic(bytesFromFile,address,port);
count++;
System.out.println("after start thread"+count);
}
catch(Exception e)
{
System.out.println("not working");
}
}
}
catch (IOException e) {}
}
}
At the end I expect my server to send the mp3 file to my client then my client will create an mp3 file that can be opened and played.
My Datagram simple client server program is giving error.Client takes information from server and server also gets information from client.
Here is my Server:
package udp;
import java.net.*;
public class DatagramServer implements Runnable {
DatagramPacket pack;
DatagramSocket sock;
DatagramServer() {
new Thread(this).start();
}
public void run() {
try {
while (true) {
recieve();
send();
}
} catch (Exception e) {
System.out.println(e);
}
}
public void send() throws Exception {
byte data[] = "This is a \n datagram packet".getBytes();
InetAddress add = InetAddress.getByName("localhost");
pack = new DatagramPacket(data, data.length, add, 8000);
sock = new DatagramSocket();
sock.send(pack);
sock.close();
}
public void recieve() throws Exception {
byte[] buffer = new byte[65536];
DatagramPacket incoming = new DatagramPacket(buffer, buffer.length);
sock = new DatagramSocket(8000);
sock.receive(incoming);
byte[] data = incoming.getData();
String s = new String(data, 0, incoming.getLength());
}
public static void main(String[] args) {
new DatagramServer();
}
}
And here is my Client :
package udp;
import java.net.*;
public class DatagramClient {
DatagramPacket pack;
DatagramSocket sock;
DatagramClient() {
Thread t1 = new Thread() {
public void run() {
while (true) {
try {
receive();
Thread.sleep(5000);
} catch (Exception e) {
System.out.println(e);
}
}
}
};
t1.start();
Thread t2 = new Thread() {
public void run() {
while (true) {
try {
send();
Thread.sleep(5000);
} catch (Exception e) {
System.out.println(e);
}
}
}
};
t2.start();
}
public void receive() throws Exception {
byte data[] = new byte[1000];
pack = new DatagramPacket(data, data.length);
sock = new DatagramSocket(8000);
sock.receive(pack);
System.out.println("Data::" + new String(pack.getData(), "UTF-8"));
System.out.println("Port::" + pack.getPort());
sock.close();
}
public void send() throws Exception {
String s = "KOLI SDF DFEF XFFFSS";
byte[] b = new byte[1000];
b = s.getBytes();
DatagramPacket dp = new DatagramPacket(b, b.length, InetAddress.getByName("localhost"), 8000);
sock= new DatagramSocket(8000);
sock.send(dp);
}
public static void main(String[] args) {
new DatagramClient();
}
}
I'm getting errors like:
java.net.BindException: Address already in use: Cannot bind
java.net.BindException: Address already in use: Cannot bind
java.net.BindException: Address already in use: Cannot bind
java.net.BindException: Address already in use: Cannot bindBUILD STOPPED (total time: 4 seconds)
What should i do?
Your client and server has some issues such as open same port 8000 in different threads so I have fixed those within the following code.
Client
package udp;
import java.net.*;
public class DatagramClient {
DatagramPacket pack;
DatagramSocket sock;
DatagramClient() {
Thread t1 = new Thread() {
public void run() {
while (true) {
try {
receive();
Thread.sleep(5000);
} catch (Exception e) {
System.out.println(e);
}
}
}
};
t1.start();
}
public void receive() throws Exception {
byte data[] = new byte[1000];
pack = new DatagramPacket(data, data.length);
sock = new DatagramSocket(8000);
sock.receive(pack);
System.out.println("Data::" + new String(pack.getData(), "UTF-8"));
System.out.println("Port::" + pack.getPort());
sock.close();
}
public void send() throws Exception {
String s = "KOLI SDF DFEF XFFFSS";
byte[] b = new byte[1000];
b = s.getBytes();
DatagramPacket dp = new DatagramPacket(b, b.length, InetAddress.getByName("localhost"), 8000);
sock= new DatagramSocket(8000);
sock.send(dp);
}
public static void main(String[] args) {
new DatagramClient();
}
}
Server
package udp;
import java.net.*;
public class DatagramServer implements Runnable {
DatagramPacket pack;
DatagramSocket sock;
DatagramServer() {
new Thread(this).start();
}
public void run() {
try {
while (true) {
//recieve();
send();
}
} catch (Exception e) {
System.out.println(e);
}
}
public void send() throws Exception {
byte data[] = "This is a \n datagram packet".getBytes();
InetAddress add = InetAddress.getByName("localhost");
pack = new DatagramPacket(data, data.length, add, 8000);
sock = new DatagramSocket();
sock.send(pack);
sock.close();
}
public void recieve() throws Exception {
byte[] buffer = new byte[65536];
DatagramPacket incoming = new DatagramPacket(buffer, buffer.length);
sock = new DatagramSocket(8000);
sock.receive(incoming);
byte[] data = incoming.getData();
String s = new String(data, 0, incoming.getLength());
}
public static void main(String[] args) {
new DatagramServer();
}
}
The problem is your server code is trying to bind to the 8000 port each time receive () called. And receive is being called repeatedly from within the while(true) loop. So it tries to bind to the same port again and again.
To fix it remove the UDP socket instantiation i.e
sock = new DatagramSocket(8000);
From the receive method and put it before your while loop begins.
What I want to do is 1) On the client side, convert a double (currently it's 1.75) to bytes[] and send it to the server using DatagramPacket; 2) On the server side, receive the request, get the bytes[] data, convert it to double and print it out.
UDPClient.java:
import java.net.*;
import java.io.*;
import java.nio.ByteBuffer;
public class UDPClient {
private static byte[] doubleToByteArray(double x) {
byte[] bytes = new byte[8];
ByteBuffer.wrap(bytes).putDouble(x);
return bytes;
}
public static void main(String args[]) {
DatagramSocket aSocket = null;
try {
aSocket = new DatagramSocket();
byte[] m = doubleToByteArray(1.75);
InetAddress aHost = InetAddress.getByName("localhost");
int serverPort = 6789;
DatagramPacket request
= new DatagramPacket(m, m.length, aHost, serverPort);
aSocket.send(request);
} catch (SocketException e) {
System.out.println("Socket: " + e.getMessage());
} catch (IOException e) {
System.out.println("IO: " + e.getMessage());
} finally {
if (aSocket != null) {
aSocket.close();
}
}
}
}
UDPServer.java:
import java.net.*;
import java.io.*;
import java.nio.ByteBuffer;
public class UDPServer {
private static double byteArrayToDouble(byte[] bytes) {
double d = 0.0;
ByteBuffer.wrap(bytes).putDouble(d);
return d;
}
public static void main(String args[]) {
DatagramSocket aSocket = null;
try {
aSocket = new DatagramSocket(6789);
// create socket at agreed port
byte[] buffer = new byte[1000];
while (true) {
DatagramPacket request = new DatagramPacket(buffer, buffer.length);
aSocket.receive(request);
System.out.println(new String(request.getData(), 0, request.getLength()));
// output: some messy characters
System.out.println(byteArrayToDouble(request.getData()));
// output: "0.0" (of course, unfortunately)
}
} catch (SocketException e) {
System.out.println("Socket: " + e.getMessage());
} catch (IOException e) {
System.out.println("IO: " + e.getMessage());
} finally {
if (aSocket != null) {
aSocket.close();
}
}
}
}
How should I modify my send/receive mechanisms so that the correct bytes are transmitted?
private static double byteArrayToDouble(byte[] bytes) {
double d = 0.0;
ByteBuffer.wrap(bytes).putDouble(d);
return d;
}
That's a strange way to convert a byte array to a double. It doesn't do anything to the double. It can't. No reference parameters in Java. It should be get. Essentially the whole method can be replaced with:
ByteBuffer.wrap(request.getData(), 0, request.getLength()).getDouble().
E&OE
I've searched for examples of how to implement a simple ipv6 multicast example, however I have only found examples using ipv4.
Can anybody provide a simple "helloworld" example of ipv6 multicasting?
Here is a simple client server example. Incidentally running it on multiple machines on a network wil get all the machines chatting to each other, good for testing automatic discovery on the network.
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class UdpBroadcaster {
private static final Logger LOGGER = LoggerFactory.getLogger(UdpBroadcaster.class);
private static final int PORT = 9876;
private static final String MCAST_ADDR = "FF7E:230::1234";
private static InetAddress GROUP;
public static void main(String[] args) {
try {
GROUP = InetAddress.getByName(MCAST_ADDR);
Thread server = server();
server.start();
Thread.sleep(3000);
Thread client = client();
client.start();
client.join();
} catch (Exception e) {
LOGGER.error("Usage : [group-ip] [port]");
}
}
private static Thread client() {
return new Thread(new Runnable() {
public void run() {
MulticastSocket multicastSocket = null;
try {
multicastSocket = new MulticastSocket(PORT);
multicastSocket.joinGroup(GROUP);
while (true) {
try {
byte[] receiveData = new byte[256];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
multicastSocket.receive(receivePacket);
LOGGER.info("Client received from : " + receivePacket.getAddress() + ", " + new String(receivePacket.getData()));
} catch (Exception e) {
LOGGER.error(null, e);
}
}
} catch (Exception e) {
LOGGER.error(null, e);
} finally {
multicastSocket.close();
}
}
});
}
private static Thread server() {
return new Thread(new Runnable() {
public void run() {
DatagramSocket serverSocket = null;
try {
serverSocket = new DatagramSocket();
try {
while (true) {
byte[] sendData = new byte[256];
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, GROUP, PORT);
serverSocket.send(sendPacket);
ThreadUtilities.sleep(1000);
}
} catch (Exception e) {
LOGGER.error(null, e);
}
} catch (Exception e) {
LOGGER.error(null, e);
}
}
});
}
}
Hope that helps.
M
The only difference between an IPv6 program and an IPv4 program in Java is the IP addresses. In this case you have to use an IPv6-style multicast address when joining the group, and when sending to it. Everything else is the same.