I have a server and a client(say client1) both on a single file working perfectly. I have a situation like: I have another client(say client2) which sends information to the server. This server has to send the information taken from client2 to client1. But when I used same port number and same IP Address on both the server and client1 when I try to send information from client2, the client1 is also accepting at a time.
How can I send the information from client2 so that first server first accepts it and then sends that information to client1?
Client2 Code:
import java.io.*;
import java.net.*;
class Client1
{
public static void main(String[] args)throws Exception {
try {
InetAddress ip=InetAddress.getByName("228.5.6.7");
int port=4270;
MulticastSocket sock=new MulticastSocket();
String msg="Hello All";
DatagramPacket packet;
while(true)
{
packet =new DatagramPacket(msg.getBytes(),msg.length(),ip,port);
sock.send(packet);
}
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
My Server and Client Code:
class Server implements Runnable
{
public void run()
{
try
{
//get the multicast ip
InetAddress ip = InetAddress.getByName("228.5.6.7");
int port=4270;
byte[] buffer=new byte[100];
byte[] data = null;
MulticastSocket sock=new MulticastSocket(port);
//join the multicast group
sock.joinGroup(ip);
while(true)
{
//create a datagram packet in which u will receive the msg
Thread.sleep(2000);
DatagramPacket pack=new DatagramPacket(buffer,buffer.length);
sock.receive(pack);
String msg = new String(buffer);
System.out.println("Sever Has Received :" +msg);
//SENDING THE MESSAGE TO CLIENT
System.out.println("Sending the Message!!!");
data = msg.getBytes();
DatagramPacket pack1 = new DatagramPacket(data,msg.length(),ip,port);
Thread.sleep(2000);
sock.send(pack1);
}
}
catch (Exception ex) {
Thread t = Thread.currentThread();
t.getUncaughtExceptionHandler().uncaughtException(t, ex);
}
}
}
Client1 Code:
class Client implements Runnable
{
public void run()
{
try {
InetAddress address1 = InetAddress.getByName("228.5.6.7");
int port=4271;
MulticastSocket socket1 = new MulticastSocket(port);
//join a Multicast group and send the group salutations
socket1.joinGroup(address1);
byte[] data1 = new byte[256];
DatagramPacket packet1 = new DatagramPacket(data1,data1.length);
while(true)
{
// receive the packets
socket1.receive(packet1);
String str = new String(packet1.getData(),0,packet1.getLength());
Thread.sleep(2000);
System.out.println("Client Received : "+str);
}
}
catch (Exception ex) {
Thread t = Thread.currentThread();
t.getUncaughtExceptionHandler().uncaughtException(t, ex);
}
}
}
MAIN PROGRAM
class ClientAndServer
{
public static void main(String[] args)
{
Server s = new Server();
//First start Server and then Start client
Thread t1 = new Thread(s);
t1.start();
Client c = new Client();
Thread t2 = new Thread(c);
t2.start();
}
}
Since you are using a MulticastSocket to link Client1 <-> Server <-> Client2. If Server send a message, EVERY client will received it, this is from the MulticastSocket doc
When one sends a message to a multicast group, all subscribing recipients to that host and port receive the message
If you don't want that, you might need to use two distinct socket, using two port
port 1 : Client1 <-> Server
port 2 : Client2 <-> Server
And you can then redirect the message only to one or the other port but will have two distinct channel of message
Related
I have a Multicast socket open and is receiving Multicast message. From this thread, it seems that the same multicast socket should also be able to receive unicast messages. However, I'm not able to get anything.
Edit: the port number seems the be problem. Port 3702 is used by ws-discovery for unicasting which is related to what I'm trying to do. I'm tracking down a problem where the client's probe to the service is not caught by the service's multicast socket. I'm running this on windows.
My multicast server:
class Server extends Thread {
MulticastSocket multicastSocket;
final Logger LOG;
final int PORT = 3702;
final String MULTICAST_ADDR = "239.255.255.250";
InetAddress multicastGroup;
public Server() {
LOG = Logger.getLogger("Server");
try {
multicastGroup = InetAddress.getByName(MULTICAST_ADDR);
multicastSocket = new MulticastSocket(PORT);
multicastSocket.setInterface(InetAddress.getLocalHost());
multicastSocket.joinGroup(multicastGroup);
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void run() {
while (!Global.exit) {
byte[] buf = new byte[1000];
DatagramPacket recv = new DatagramPacket(buf, buf.length);
try {
multicastSocket.receive(recv);
String msg = new String(recv.getData(), StandardCharsets.UTF_8);
LOG.log(Level.INFO, "got: " + msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
And the client code:
public void directMsgTest(){
try {
DatagramSocket datagramSocket = new DatagramSocket( 8080,InetAddress.getLocalHost());
String msg = "direct msg";
byte[] buf = msg.getBytes();
DatagramPacket packet = new DatagramPacket(buf, buf.length, InetAddress.getLocalHost(), DST_PORT);
datagramSocket.send(packet);
datagramSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
It seems that this is Window's fault. It uses WS discovery in some of its services, thus using port 3702 and eating unicast packets send to port 3702 instead of giving it to my server.
I tried running this on Linux and it was fine.
For my class project I have the following problem. I am able to receive client information and re-send the info to the respective client. However, I am not being able to send every clients' info to every other client (Broadcast?). I also need to implement the given functions. Any help would be appreciated.
The goal is to design and implement a simple application layer protocol over UDP to
facilitate High Availability Cluster (HAC). HAC has a set of mechanism to detect failovers,
network/node failure etc. in order to re-route the traffic to the available systems. In this project
you will not be working on the questions like how to perform consistent failover, or high
availability distributed hypervisor. However, your task is to design and implement a protocol to
maintain the up-node information throughout the cluster.
Your designed protocol should perform the following functions:
a) To detect node failure periodically
b) To inform the other nodes in the network about the failure (peering option)
c) To be able to detect when the failed node comes back to life
d) To inform other nodes about the availability of new node
Client Class:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.*;
import java.util.Random;
public class UDPClient
{
DatagramSocket Socket;
public UDPClient()
{
}
public void createAndListenSocket() throws ClassNotFoundException, InterruptedException
{
try
{
Socket = new DatagramSocket();
InetAddress IPAddress = InetAddress.getByName("localhost");
byte[] incomingData = new byte[1024];
String sentence = "Client 1 is up";
byte[] data = sentence.getBytes();
boolean flag = true;
CreatePacket packet = new CreatePacket(data, flag, data.length);
while(true)
{
//Serialize to send
Random rnd = new Random();
int timeout = rnd.nextInt(30);
Thread.sleep(timeout*1000);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(buffer);
out.writeObject(packet);
out.close();
buffer.close();
DatagramPacket sendPacket = new DatagramPacket(buffer.toByteArray(), buffer.size(), IPAddress, 9876);
Socket.send(sendPacket);
System.out.println("Message sent from client");
//Deserialize and receive packet from server
DatagramPacket incomingPacket = new DatagramPacket(incomingData, incomingData.length);
Socket.receive(incomingPacket);
ByteArrayInputStream bis = new ByteArrayInputStream(incomingPacket.getData());
ObjectInputStream in = new ObjectInputStream(bis);
Object receivedPacket = in.readObject();
in.close();
InetAddress IPAddress1 = incomingPacket.getAddress();
int port = incomingPacket.getPort();
System.out.println();
System.out.println("Response from server: ");
System.out.println("Message : " + receivedPacket.toString());
System.out.println("Client IP: "+ IPAddress1.getHostAddress());
System.out.println("Client port: "+ port);
}
}
catch (UnknownHostException e)
{
e.printStackTrace();
}
catch (SocketException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception
{
UDPClient client = new UDPClient();
client.createAndListenSocket();
}
}
Server code:
public class UDPServer
{
DatagramSocket socket = null;
public UDPServer()
{
}
public void createAndListenSocket() throws ClassNotFoundException
{
try
{
socket = new DatagramSocket(9876);
byte[] incomingData = new byte[1024];
while (true)
{
DatagramPacket incomingPacket = new DatagramPacket(incomingData, incomingData.length);
socket.receive(incomingPacket);
CreatePacket toSendPacket = new CreatePacket(incomingData, incomingData.length);
ArrayList <CreatePacket> clients = new ArrayList<CreatePacket>(4);
ByteArrayInputStream bis = new ByteArrayInputStream(incomingPacket.getData());
ObjectInputStream in = new ObjectInputStream(bis);
Object receivedPacket = in.readObject();
in.close();
clients.add(toSendPacket);
InetAddress IPAddress = incomingPacket.getAddress();
int port = incomingPacket.getPort();
System.out.println();
System.out.println("" + receivedPacket.toString());
System.out.println("Client IP: "+ IPAddress.getHostAddress());
System.out.println("Client port: "+ port);
DatagramPacket replyPacket = new DatagramPacket(incomingData, incomingData.length, IPAddress, port);
Thread.sleep(10*1000);
socket.send(replyPacket);
//socket.close();
}
}
catch (SocketException e)
{
e.printStackTrace();
}
catch (IOException i)
{
i.printStackTrace();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
public static void main(String[] args) throws ClassNotFoundException, IOException
{
UDPServer server = new UDPServer();
server.createAndListenSocket();
}
}
You want
1 - client to send message to server if it is up/alive
2 - and for server to send some message to all client if it receives signal right?
I am not sure but you can try this,
InetAddress IPAddress = incomingPacket.getAddress();
int port = incomingPacket.getPort();
as you are getting IP address of one client you can store address of all clients on server side which are up/alive in a List or array. Then if you receives signal to server use that list to send respond.
You will need to update list according to up/alive clients.
I created a chat application to sent messages to a multicast group conversation with multiple clients.
The message has to been send to the MulticastServer and sent to all client on Multicast Group. At this point, the message arrive at the server from client in perfect conditions.
But when i reply back to client (even a simple String), the message is sending only to the client that send the message and not for all users in the Multicast Group.
The StackTrace doesn't give me any error, but i still getting this issue.
I give you some of the important code. The following one refering the connection to multicast server. The DEFAULT_ADRESS is 224.0.0.3.
socket = new MulticastSocket();
address = InetAddress.getByName(DEFAULT_ADRESS);
socket.joinGroup(address);
The part of the code that send a message to MulticastServer:
String messtoSendServer = utilizadorOnline.getNome() + ":" + textfieldtocomunicateGroupe.getText();
buf = messtoSendServer.getBytes();
packet = new DatagramPacket(buf, buf.length, address, DEFAULT_PORT);
try {
// userOnline_Multicast.getSocketMulti().send(packet);
socket.send(packet);
} catch (IOException ex) {
Logger.getLogger(ConversaGrupo.class.getName()).log(Level.SEVERE, null, ex);
}
The part of the code that receive the message from server:
private void receberDadosServidor() throws IOException {
try {
DatagramPacket packet1 = new DatagramPacket(buf, buf.length);
socket.receive(packet1);
String received = new String(packet1.getData());
textareatoGroupChat.setText(textareatoGroupChat.getText() + "\n" + received);
} catch (IOException ex) {
Logger.getLogger(ConversaGrupo.class.getName()).log(Level.SEVERE, null, ex);
socket.close();
socket.leaveGroup(address);
}
This is the Server Side. First start the Thread:
public void run(JTextArea txtArea) throws IOException {
new MulticastServerThread(txtArea).start();
}
And the Thread herself:
public class MulticastServerThread extends Thread {
private final String DEFAULT_MULTICASTIP = "224.0.0.3";
private final int DEFAULT_MULTICASTPORT = 4446;
private final int FIVE_SECONDS =5000;
private DatagramPacket packet;
private JTextArea textA;
private boolean moreQuotes = true;
private MulticastSocket socket = null;
private InetAddress adresstoConnectMulticast = null;
public MulticastServerThread(JTextArea txt) throws IOException {
super("MulticastServerThread");
this.textA = txt;
}
#Override
public void run() {
while (true) {
try {
byte[] buf = new byte[1024];
socket = new MulticastSocket(DEFAULT_MULTICASTPORT);
adresstoConnectMulticast = InetAddress.getByName(DEFAULT_MULTICASTIP);
socket.joinGroup(adresstoConnectMulticast);
packet = new DatagramPacket(buf, buf.length, adresstoConnectMulticast, DEFAULT_MULTICASTPORT); //usado para receber um datagram do socket, o array de bytes contem dados do cliente especifico
socket.receive(packet);
String mensagem = new String(packet.getData()).trim();
textA.setText(textA.getText() + "\n\nServer Multicast Receive from User:" + mensagem +" on IP Multicast " +DEFAULT_MULTICASTIP +" | "+ DEFAULT_MULTICASTPORT);
buf = mensagem.getBytes();
InetAddress ed = packet.getAddress();
int portad = packet.getPort();
//manda de volta para o cliente.
packet = new DatagramPacket(buf, buf.length, ed, portad);
socket.send(packet);
try {
sleep((long) Math.random() * FIVE_SECONDS);
} catch (InterruptedException e) {
}
} catch (IOException ex) {
Logger.getLogger(MulticastServerThread.class.getName()).log(Level.SEVERE, null, ex);
socket.close();
}
}
}
}
There are several problems here.
socket = new MulticastSocket();
Your clients all need to be bound to the same port. Provide a fixed port number to the constructor. Otherwise you get a system-allocated port.
Second, your server replies to the source's IP address and port number. It should reply to the group IP address and the source's port number, or the fixed port number above, which should be the same.
Third, 224.0.0.3 is reserved. You can't use it.
And leave the server's socket open. Don't open and close it every time around the loop.
I have a problem to run a server and clients in one (mac) machine. I can run the server but when I run the client it give me an error java.net.BindException: Address already in use
at java.net.PlainDatagramSocketImpl.bind0(Native Method)
as far as I know that there is somthing call ssh that need to be used but I don't know how to use it to do solve this.
Thanks
public class WRRCourseWork {
public static void main(String[] args) {
try {
DatagramSocket IN_socket = new DatagramSocket(3000);
DatagramSocket OUT_socket = new DatagramSocket(5000);
IN_socket.setSoTimeout(0);
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while (true) {
//recive the message
IN_socket.receive(packet);
String message = new String(buffer);
System.out.println("Got message: " + message.trim());
// send the message
String host = "";
InetAddress addr = InetAddress.getByName(host);
DatagramPacket OUT_Packet = new DatagramPacket(message.getBytes(), message.getBytes().length, addr, 5000);
OUT_socket.send(OUT_Packet);
System.out.println("Sending Message: "+ message.trim());
}
} catch (Exception error) {
error.printStackTrace();
}
}
... client
public class Messages {
public static void main(String [] args) {
System.out.println("hiiiiiii");
//String host = "localhost";
try {
while (true) {
InetAddress addr = InetAddress.getLocalHost();
String message = "Hello World";
DatagramPacket packet = new DatagramPacket(message.getBytes(), message.getBytes().length, addr, 4000);
DatagramSocket socket = new DatagramSocket(4000);
socket.send(packet);
//socket.close();
}
} catch(Exception error) {
// catch all errors
error.printStackTrace();
}
}
}
Your server is listening on port 3000 so change your client to also use port 3000 and to only specify port 3000 once, in the packet definition not in the socket.
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class Messages {
public static void main(String [] args) {
System.out.println("hiiiiiii");
//String host = "localhost";
DatagramSocket socket = null;
try {
while (true) {
InetAddress addr = InetAddress.getLocalHost();
String message = "Hello World";
DatagramPacket packet =
new DatagramPacket(message.getBytes(),
message.getBytes().length, addr, 3000);
socket = new DatagramSocket();
socket.send(packet);
socket.close();
}
} catch(Exception error) {
// catch all errors
error.printStackTrace();
}
}
}
The results on the server should then be:
Got message: Hello World
Sending Message: Hello World
Got message: Hello World
Sending Message: Hello World
Got message: Hello World
Sending Message: Hello World
. . .
my android device is connected to my home-wireless-network. Also a special UDP-device is connected to it. My android app successfully can send commands to the UDP-device. But if I open a socket it does not receive data. Can you see what is wrong? I know the ip of the UDP-device from the iphone-APP which is working
Here is how the app send commands:
public static final String SERVERIP = "192.168.2.114";
public static final int PORT = 44444;
public void run() {
try {
serverAddr = InetAddress.getByName(SERVERIP);
DatagramSocket socket = new DatagramSocket();
byte[] buf = message.toByteArray();
DatagramPacket packet = new DatagramPacket(buf, buf.length, serverAddr, PORT);
socket.send(packet);
socket.close();
} catch (Exception e) {
Log.e("UDP", "Sender/Client: Error", e);
}
}
Whereas I have two approaches for receiving data:
public static final String SERVERIP = "192.168.2.114";
public static final int SERVERPORT = 44445;
private InetAddress serverAddr;
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVERIP);
DatagramSocket socket = new DatagramSocket(SERVERPORT, serverAddr);
byte[] buf = new byte[65213];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
} catch (Exception e) {
Log.e("UDP", "Receiver: Error", e);
}
try {
serverAddr = InetAddress.getByName(SERVERIP);
DatagramChannel channel = DatagramChannel.open();
DatagramSocket socket = channel.socket();
byte[] buf = new byte[65213];
DatagramPacket packet = new DatagramPacket(buf, buf.length, serverAddr, SERVERPORT);
socket.receive(packet);
socket.close();
} catch (Exception e) {
Log.e("UDP", "Sender/Client: Error", e);
}
}
The approach in the first try block leads to an exception:
java.net.BindException: Cannot assign requested address
at org.apache.harmony.luni.platform.OSNetworkSystem.bind(Native Method)
at dalvik.system.BlockGuard$WrappedNetworkSystem.bind(BlockGuard.java:268)
at org.apache.harmony.luni.net.PlainDatagramSocketImpl.bind(PlainDatagramSocketImpl.java:81)
at java.net.DatagramSocket.createSocket(DatagramSocket.java:193)
at java.net.DatagramSocket.<init>(DatagramSocket.java:95)
at de.myappname.connection.Receiver.run(Receiver.java:29)
at java.lang.Thread.run(Thread.java:1019)
The second approach just blocks the thread by socket.receive(packet) which does not receive data. From the iphone and specification I know the device sends data via UDP 44445 over WLAN. Any suggestions what is wrong?
Thank you!
UDP port 44445 is used by eMule protocol. Do you have any other eMule clients active on your device?
Update:
The problem seems to be the address you bind to - it must be an address on the localhost, i.e. IP address of your device, not remote device. See DatagramSocket(port, InetAddress) constructor.
I guess you need to put the receive() function inside a while loop since you current code looks like it receives message only once; it doesn't guarantee that it will contain any valid data.