So I try to create a simple server client application.
I have the server, which multicast messages to the subscribed clients.
The clients can obviously subscribe or unsubscribe.
Here is the server side code for the socket
try // create DatagramSocket for sending and receiving packets
{
socket = new DatagramSocket( 6666 );
} // end try
catch ( SocketException socketException )
{
System.exit( 1 );
} // end catch
I have also created a thread which waits for incoming pockets
while(true)
{
try // receive packet, display contents, return copy to client
{
byte[] data = new byte[ 100 ]; // set up packet
DatagramPacket receivePacket =
new DatagramPacket( data, data.length );
socket.receive( receivePacket ); // wait to receive packet
String Message = receivePacket.getData().toString();
.........
Here is the client side
try {
socket = new DatagramSocket();
} catch (SocketException ex) {
displayArea.append( ex + "\n" );
}
Here I try to send the packet
byte[] data = message.getBytes(); // convert to bytes
try {
// create sendPacket
DatagramPacket sendPacket = new DatagramPacket( data,
data.length, InetAddress.getLocalHost(), 6666 );
} catch (UnknownHostException ex) {
displayArea.append( ex + "\n" );
}
Well, the problem is that I don't think the packet reaches the server, I know the thread is waiting for the packet, I can see in debug that it does reaches the socket.receive part, however, nothing happens.
I'm using the client and server on the same computer.
Any idea what am I doing wrong?
Thanks.
byte[] data = message.getBytes(); // convert to bytes
try {
DatagramPacket sendPacket =
new DatagramPacket( data, data.length, InetAddress.getLocalHost(), 6666 );
socket.send( sendPacket ); //<<<<<<<<<<<<<<<<<<< REQUIRED
}
catch( UnknownHostException ex ) {
displayArea.append( ex + "\n" );
}
Related
Say I start a simple UDP server: nc -u localhost 10000
And a simple UDP client: nc -ul 10000
Then is it possible, in Java, to receive the messages sent by the server without getting an "Address already in use" exception because there's already a client?
EDIT: here's the code I'm using:
DatagramSocket socket = new DatagramSocket(port);
new Thread(() -> {
try {
while(true) {
byte[] receiveData = new byte[256];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
socket.receive(receivePacket);
String message = new String( receivePacket.getData(), 0, receivePacket.getLength()).trim();
}
}
catch (SocketException ignore) {}
catch (IOException e) { e.printStackTrace(); }
}).start();
This leads to a java.net.BindException: Address already in use (bind failed).
Using this:
DatagramSocket socket = new DatagramSocket(null);
socket.setOption(SO_REUSEPORT, true);
socket.setOption(SO_REUSEADDR, true);
new Thread(() -> {
try {
while(true) {
byte[] receiveData = new byte[256];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
socket.receive(receivePacket);
String message = new String( receivePacket.getData(), 0, receivePacket.getLength()).trim();
}
}
catch (SocketException ignore) {}
catch (IOException e) { e.printStackTrace(); }
}).start();
Produces no exception but I won't receive the messages sent by the server.
EDIT 2: in the real situation, the server is broadcasting messages.
This should be possible by utilizing StandardSocketOptions.SO_REUSEPORT:
For datagram-oriented sockets the socket option usually allows multiple UDP sockets to be bound to the same address and port.
The Linux Kernel supports this since 3.9.
On Windows, you might need to utilize SO_REUSEADDR, but I'm not exactly sure.
Using SO_REUSEADDR
The SO_REUSEADDR socket option allows a socket to forcibly bind to a port in use by another socket.
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!
I am trying to get UDP packets ,sent by device via WiFi, on my pc.
The device (kind of card) send every 2 seconds new packet.
The problem is that i do not get the packets on java client i have on my pc.
I see the packets on Wireshark.
Here is my UDP client (java):
public static void main(String args[]) {
try {
int port = 80;
// Create a socket to listen on the port.
DatagramSocket dsocket = new DatagramSocket(port);
dsocket.setSoTimeout(10000);
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
try
{
dsocket.receive(packet);
}
catch (SocketTimeoutException e) {
continue;
}
// 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);
}
}
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;
}
}
}
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);
}