I need to send and receive in multicast.
This is my Sender:
public static void main(String[] args) {
MulticastSocket socket = null;
try {
socket = new MulticastSocket(3575);
int n = 1;
while (n <= 100) {
byte[] buf = new byte[256];
// non aspetta la richiesta
String dString = new Date().toString();
buf = dString.getBytes();
// invia il messaggio in broadcast
InetAddress group = InetAddress.getByName("230.0.0.1");
DatagramPacket packet = new DatagramPacket(buf, buf.length, group, 3575);
socket.send(packet);
System.out.println ("Broadcasting: "+dString);
Thread.sleep(1000);
n++;
}
socket.close();
}catch(Exception e) { e.printStackTrace(); socket.close();}
}//main
This is my Receiver:
public static void main(String[] args) throws IOException {
MulticastSocket socket = new MulticastSocket(3575);
InetAddress group = InetAddress.getByName("230.0.0.1");
socket.joinGroup(group);
DatagramPacket packet;
for (int i = 0; i < 100; i++) {
byte[] buf = new byte[256];
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
String received = new String(packet.getData()).trim();
System.out.println("Time: " + received);
}
socket.leaveGroup(group);
socket.close();
}//main
When I run them, the Receiver does not receive anything.
I tried on two different PC ( both with Windows) with AntiVirus and firewall disabled. I also tried with different LAN: my router, my phone hotspot.
It does not work neither on local machine.
How can I solve the problem?
Thanks
I compiled and ran your code on my laptop, with the sender and receiver on the same machine. It works. (Fedora 26 Linux, Java 1.8.0_171)
It seems that the problem is something to do with your networking, not the application code. So, since this not a programming problem, I think you would be better off asking this Question on the ServerFault site ... where they specialize in networking, etcetera.
Related
i shall implement a UDP-based client/server application and im new in the world of Java. The Server implements a simple request-acknowledge protocol upon the UDP protocol. For a received string identifier (command) with optional parameters the server returns a specified result. For example "thread" returns a random integer number between 1 and 5 and length returns a random integer number between 5 and 25.
The questions is did i do the implementation right and how can i fix my problem (length nr is always between 1 and 5). I think my problem is that in the server class the if statements are not checked. Is there some other way to send a comand to a server i tried here to do it with sending strings then trying to check it with if statements?
and thats my code (Server):
public class server {
public static void main(String[] args) throws IOException, InterruptedException {
DatagramSocket skt;
try {
skt = new DatagramSocket(1252);
byte [] buffer = new byte[1000];
while(true){
DatagramPacket request = new DatagramPacket(buffer, buffer.length);
skt.receive(request);
String arrayMsg = new String(request.getData());
System.out.println(arrayMsg);
//check if the client asks for threadnr
if(arrayMsg.equals("thread")){
int threadnumber = (int) (Math.random()*5)+1;
String threadnum = Integer.toString(threadnumber);
byte [] b = threadnum.getBytes();
DatagramPacket reply = new DatagramPacket(b, b.length, request.getAddress(), request.getPort());
skt.send(reply);;}
//check if the client asks for lengthnr
else if(arrayMsg.equals("length")){
int lengthnumber = (int) (Math.random()*25)+5;
String lengthnum = Integer.toString(lengthnumber);
byte [] b = lengthnum.getBytes();
DatagramPacket reply = new DatagramPacket(b, b.length,request.getAddress(), request.getPort());
skt.send(reply);}
}}
catch (SocketException e) {
System.out.println("UDP Port 9876 is occupied.");
System.exit(1);
}}}
thats my Client:
public class client {
public static void main(String[] args) throws UnknownHostException, IOException {
DatagramSocket skt = new DatagramSocket();
InetAddress host = InetAddress.getByName("localhost");
int serverSocket = 1252;
byte [] senddata = new byte [1000];
byte [] getdata = new byte[1000];
//thread send request
String th = "thread";
senddata = th.getBytes();
DatagramPacket requestth = new DatagramPacket(senddata, senddata.length, host, serverSocket);
skt.send(requestth);
//thread get reply
DatagramPacket replyth = new DatagramPacket ( getdata, getdata.length);
skt.receive(replyth);
String arrayth = new String(replyth.getData());
int threadnr=Integer.parseInt(arrayth.trim()); //convert thread string to int and trim it (whitespace)
System.out.println("Thread received " + threadnr);
//length send request
String lg = "length";
senddata = lg.getBytes();
DatagramPacket requestlg = new DatagramPacket(senddata, senddata.length, host, serverSocket);
skt.send(requestlg);
//length get reply
DatagramPacket replylg = new DatagramPacket ( getdata, getdata.length);
skt.receive(replylg);
String arraylg = new String(replyth.getData());
int lengthnr=Integer.parseInt(arraylg.trim()); //convert thread string to int and trim it (whitespace)
System.out.println("Length received " + lengthnr);
skt.close();
And all i get is something like this:
Thread received 3
Length received 1
(Length should be between 5 and 25 and in my case its never bigger then 5)
The code parses the response from the first message instead of from the last, so you get the random 1-5. I suggest using better names for the variables and you'll spot the problem quicker.
I'm having a weird problem, let's consider the following code :
import java.net.*;
import java.util.Enumeration;
public class Main{
public static void main(String args[]) throws Exception {
Inet4Address myIp = (Inet4Address)Inet4Address.getByName(Main.getLanIp());
InetSocketAddress myAddr = new InetSocketAddress(myIp, LocalportNumber);
if(myIp == null){
throw new Exception();
}
DatagramSocket socket = new DatagramSocket(myAddr);
socket.setReuseAddress(true);
InetAddress IPAddress = InetAddress.getByName("239.xxx.xxx.xxx");
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
String sentence = "PAYLOAD";
sendData = sentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, distantPortNumber);
DatagramPacket receivePacket = new DatagramPacket(receiveData, 1024);
socket.send(sendPacket);
System.out.println("Packet sent");
socket.receive(receivePacket);
String modifiedSentence = new String(receivePacket.getData());
System.out.println("FROM SERVER:" + modifiedSentence);
socket.close();
}
static public String getLanIp() throws SocketException{
InetAddress inet_addr = null;
NetworkInterface cur = null;
for (Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); interfaces.hasMoreElements();){
cur = interfaces.nextElement();
try {
if (cur.isLoopback())
{
continue;
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("interface " + cur.getName());
for (InterfaceAddress addr : cur.getInterfaceAddresses()){
inet_addr = addr.getAddress();
if ( !( inet_addr instanceof Inet4Address)){
continue;
}
System.out.println(" address: " + inet_addr.getHostAddress() + "/" + addr.getNetworkPrefixLength());
System.out.println(" broadcast address: " + addr.getBroadcast().getHostAddress());
}
}
return inet_addr.getHostAddress();
}
}
Execution trace :
"""
interface eth0
address: 192.168.0.20/24
broadcast address: 192.168.0.255
Packet sent
"""
When I run the preceding code, a packet is sent, the server answers but I still block on the receive method, I can see the incoming packet on wireshark reaching my computer. But when I try a : "netstat -npl", I see a java process listening on the port localPort. I tried a "nc -vvv -u 9393" from remote (lan) and then typed random sentences ... Nothing happened. I tried the same on local (with my external IP, with my loopback IP), same problem. Is there a list of known problems which could block the received udp packets between the kernel and the jvm ?
I found my problem : my iptable firewall ... I was blocking all the incoming traffic which was not an answer to my outgoing traffic. That's why I saw the traffic on wireshark but I didn't reached the java socket...
So the solution was to open my firewall -_-"
I am working on a simple audio streamer with multicast. I wrote serer and client on the same machine, so I worked with localhost and multicast-groups. The system works on one machine but when I tried to use another PC as the server, I can't get them to connect. Here is the situation:
The client first knocks on a tcp-server which lets the client know the multicasting-group IP an port. After this, the client starts listining to the address via multicastSocket.receive();.
Here are the important bits from the system:
(I left out the exceptions and other non-important stuff in the following code)
Server
Important to know is that the "LAN-Connection" is the name of my network interface on the servers system.
int multicastPort = 8888;
InetAddress multicastIP = InetAddress.getbyName("228.5.6.7");
InetSocketAddress multicastAddress = new inetSocketAddress( multicastIP, multicastPort );
NetworkInterface multicastInterface = NetworkInterface.getByName( "LAN-Connection" );
MulticastSocket multicastSocket = new MulticastSocket( multicastPort );
multicastSocket.joinGroup( multicastAddress, multicastIP);
while(true) {
byte [] buffer = audioIn.readBytes();
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, multicastIP, multicastPort);
multicastSocket.send(packet );
}
Client
The client requests the multicast-IP and Port from the server. (a tcp-server-thread handles this) Like with the server "LAN-Connection" is the name of the clients network interface.
int multicastPort = server.request("port");
String multicastIP_String = server.request("IP");
InetAddress multicastIP = InetAddress.getbyName(multicastIP_String );
InetSocketAddress multicastAddress = new inetSocketAddress( multicastIP, multicastPort );
NetworkInterface multicastInterface = NetworkInterface.getByName( "LAN-Connection" );
MulticastSocket multicastSocket = new MulticastSocket( multicastPort );
multicastSocket.joinGroup( multicastAddress, multicastIP);
while(true) {
byte [] buffer = new byte[2048];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
multicastSocket.receive(packet);
}
The TCP connection for requesting / sending the multicast IP and port works. An application called CurrPorts also tells me, that the correct ports get reserved, however, with wireshark, I can't find any packets sended / received neither on the clients system nor the server system. (I watched port 88 but there is no traffic,...)
Both PCs are connected to one router(D-Link DIR-635) and i guess I would have noticed If multicasting woudl be blocked by the router, right?
What am I missing? Shoudl I try different ports or IPs or could something block the packets? I only use windows firewall and I even turned this thing off for a test.
Here is a running example. I have no problem running this on the same machine but when I run the server on my laptop in the same network, nothing works.
Server
package multicastserver;
import java.net.*;
public class MulticastServer {
public static void main(String[] args) {
int multicastPort = 8888;
try {
InetAddress multicastIP = InetAddress.getByName("228.5.6.7");
InetSocketAddress multicastAddress = new InetSocketAddress( multicastIP, multicastPort );
NetworkInterface multicastInterface = NetworkInterface.getByName( "LAN-Verbindung" );
MulticastSocket multicastSocket = new MulticastSocket( multicastPort );
multicastSocket.joinGroup(multicastAddress, multicastInterface);
int counter = 0;
while(true) {
String message = "This is server, packet nr. " + counter;
counter++;
byte [] buffer = message.getBytes("UTF-8");
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, multicastIP, multicastPort);
multicastSocket.send(packet);
System.out.println("Sended: " + message);
Thread.sleep(500);
}
} catch (Exception e) {
System.out.println(e);
return;
}
}
}
Client
package multicastclient;
import java.net.*;
public class MulticastClient {
public static void main(String[] args) {
int multicastPort = 8888;
try {
InetAddress multicastIP = InetAddress.getByName("228.5.6.7");
InetSocketAddress multicastAddress = new InetSocketAddress( multicastIP, multicastPort );
NetworkInterface multicastInterface = NetworkInterface.getByName( "LAN-Verbindung" );
MulticastSocket multicastSocket = new MulticastSocket( multicastPort );
multicastSocket.joinGroup(multicastAddress, multicastInterface);
while(true) {
byte [] buffer = new byte[40];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
multicastSocket.receive(packet);
buffer = packet.getData();
String message = new String(buffer, "UTF-8");
System.out.println("Received: " + message);
}
} catch (Exception e) {
System.out.println(e);
return;
}
}
}
This is more a follow up to a previous question asked earlier however I have modified my original code now, to be able to send a file Instead of text) via a UDP socket with a specific packet size. The program runs perfectly if I specify a 1, 2 or 4 byte packet, however if I try for anything larger, such as a 8, 16 etc, the program grinds to a halt. No exception is thrown in the console, however Netbeans shows a tiny warning symbol in the bottom right hand corner and shows the following.
java.lang.IllegalArgumentException: Contents must be presorted - added value 42318 is less than preceding value 42320
at org.netbeans.core.output2.IntList.add(IntList.java:76)
at org.netbeans.core.output2.AbstractLines.addTabAt(AbstractLines.java:1122)
at org.netbeans.core.output2.OutWriter.doWrite(OutWriter.java:452)
at org.netbeans.core.output2.OutWriter.write(OutWriter.java:506)
at java.io.PrintWriter.write(PrintWriter.java:456)
at java.io.PrintWriter.write(PrintWriter.java:473)
at org.apache.tools.ant.module.bridge.impl.ForkedJavaOverride$Copier.maybeFlush(ForkedJavaOverride.java:350)
at org.apache.tools.ant.module.bridge.impl.ForkedJavaOverride$Copier.access$000(ForkedJavaOverride.java:251)
at org.apache.tools.ant.module.bridge.impl.ForkedJavaOverride$Copier$1.run(ForkedJavaOverride.java:271)
at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:1432)
[catch] at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:2044)
Is this error thrown because of the UDP Packets being received out of order by any chance? Is there a way to ignore this? I can tell the program has ceased as the string of "The End" does not appear. Does anyone know why this may be? My code for my client socket is attached below (its a bit of a long one and lots of comments for my own sanity). Many thanks in advance for any guidance.
public class UDPClient extends variable {
// static Integer portNo = 4444;
static Integer byteSize = 16;
public static void main(String[] args) throws Exception { //taken out main from here
SocketForm form = new SocketForm();
File file=null;
long startTime; // Starting time of program, in milliseconds.
long endTime; // Time when computations are done, in milliseconds.
double time;
//get server address
String serverName = "localhost";
if (args.length >= 1)
serverName = args[0];
InetAddress serverIPAddress = InetAddress.getByName(serverName);
//get server port;
int serverPort = form.cliportNo;
if (args.length >= 2)
serverPort = Integer.parseInt(args[1]);
//create socket
DatagramSocket clientSocket = new DatagramSocket();
//get input from keybaord
byte[] sendData = new byte[byteSize];
//BufferedReader inFromUser = new BufferedReader(new InputStreamReader (System.in));
//while (true){
//String sentence = inFromUser.readLine();
startTime = System.currentTimeMillis();
//sendData = sentence.getBytes();
String fileName = "/Users/Andrew/Desktop/pic.jpg";
File f = new File(fileName);
FileInputStream fis = null;
try {
fis = new FileInputStream(f);
System.out.println("Total file size to read in bytes is : " + fis.available());
} catch (IOException e) {}
Path path = Paths.get("/Users/Andrew/Desktop/pic.jpg");
//byte[] data = Fles.readAllBytes(path);
sendData = Files.readAllBytes(path);
try {
for( int index = 0; index < sendData.length ; index += byteSize ) {
DatagramPacket packet = new DatagramPacket( sendData, index, Math.min( byteSize, sendData.length-index ), serverIPAddress, serverPort);
clientSocket.send(packet);
//DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, serverIPAddress, serverPort);
//receive datagram
byte[] receiveData = new byte [byteSize];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
//print output
String sentenceFromServer = new String(receivePacket.getData());
System.out.println("From Server:" + sentenceFromServer);
}
System.out.println("The End");
}
catch (Exception e) {}
//close client socket
//clientSocket.close();
endTime = System.currentTimeMillis();
time = endTime - startTime;
System.out.println("Time :" + time);
// }
} //end of main
} //end of UDPClient
Solved. Was running 7.3 of Netbeans. It is a known issue in 7.3 and has been addressed in the latest revision of 7.4. Solution : Update to Netbeans 7.4. Now purring like a cat. Thanks to all those who tried to help with this!
I am trying to program a Java stop-and-wait UDP server and I have gotten this far with the server but I am not sure where to go next. I want the client to send a message to the server, set a timeout, wait for a response, if it doesn't get one, then resend the packet, if it does then increment the sequence no. until it get to ten and keep send and receiving messages with the server.
I have gotten this far, how do I fix this ? :
import java.io.*;
import java.net.*;
public class Client {
public static void main(String args[]) throws Exception {
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
InetAddress IPAddress = null;
try {
IPAddress = InetAddress.getByName("localhost");
} catch (UnknownHostException exception) {
System.err.println(exception);
}
//Create a datagram socket object
DatagramSocket clientSocket = new DatagramSocket();
while(true) {
String sequenceNo = "0";
sendData = sequenceNo.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 6789);
clientSocket.send(sendPacket);
clientSocket.setSoTimeout(1);
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
if(clientSocket.receive(receivePacket)==null)
{
clientSocet.send(sendPacket);
}else { //message sent and acknowledgement received
sequenceNo++; //increment sequence no.
//Create a new datagram packet to get the response
String modifiedSentence = sequenceNo;
//Print the data on the screen
System.out.println("From : " + modifiedSentence);
//Close the socket
if(sequenceNo >= 10 ) {
clientSocket.close();
}
}}}}
The first problem I can see (apart from the mistyped variable names which will stop your code compiling) is your socket timeout: if the socket timeout expires, the receive function will throw a SocketTimeoutException which your code does not handle. receive does not return a value, so the result can't be compared with null. Instead, you need to do something like this:
try {
clientSocket.receive(receivePacket);
sequenceNo++;
... // rest of the success path
} catch (SocketTimeoutException ex) {
clientSocket.send(sendPacket);
}