continuous UDP request to the server not work as expected - java

Currently I am working on a performance testing tool and I have to develop a UDP request testing plugin for load testing. I tried to send continuous large number of request to monitor the maximum load that server could handle. My goal is to make the application not responsive by sending maximum number of requests but i am not getting the expected result. My testing application is up and running in my local environment. Is it the fault of the implementation or the configurations. Please help.
//UDPRequests.groovy
package com.udp.testsubject;
import java.security.SecureRandom;
public class UDPRequests {
static void main(String [] args) {
DatagramSocket socket = null;
InetAddress address = null;
byte[] buf = new byte[65507];
SecureRandom random = new SecureRandom();
//following paramters will get from a property file
String ipAddr = '127.0.0.1';
int portDst = 4445;
int numberOfRequests = 1200000;
socket = new DatagramSocket();
address = InetAddress.getByName(ipAddr);
random.nextBytes(buf);
DatagramPacket packet = new DatagramPacket(buf, buf.length, address, portDst);
try {
printf("[*] Start send requests to %s:%d\n", ipAddr, portDst);
int count=0;
while (count < numberOfRequests) {
count++;
socket.send(packet);
}
} catch (IOException e) {
e.printStackTrace();
}
socket.close();
}
}

Related

Sending Unicast packets to a Multicast port

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.

Facilitate High availability cluster(HAC) in Java

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.

Sending Datagram Packets in Java

I am writing a program to send an integer (variable called intToSend) over a network using UDP. I run the program on two machines on the same network, one after the other. I thought that after running them both, the first one to be run would open a message box with the sent integer, but this doesn't happen. Both programs wait for a packet to be received as shown by "Waiting..." being printed to the console. I have the program ask for the destination ip to be input to the console. Then after that, the createSocket method is called, followed by sendData and then receiveData.
Here is the code:
package main;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class Main {
Scanner s = new Scanner(System.in);
PrintStream o = System.out, e = System.err;
InetAddress thisAddr, destAddr;
DatagramSocket socket;
int port = 1729, intToSend = 8;
boolean running = true;
public static void main(String[] args) {
new Main();
}
private Main() {
try {
thisAddr = InetAddress.getLocalHost();
System.out.println("Internal IP: " + thisAddr.getHostAddress().toString());
System.out.println("External IP: " + getIp());
} catch (Exception e) {
e.printStackTrace();
}
try {
destAddr = InetAddress.getByName(getDestIp());
} catch (UnknownHostException e) {
e.printStackTrace();
}
createSocket();
sendData();
receiveData();
}
private void receiveData(){
byte[] receiveBuffer = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);
while(true){
System.out.println("Waiting...");
try {
socket.receive(receivePacket);
} catch (IOException e) {
e.printStackTrace();
}
String receivedText = new String(receivePacket.getData());
JOptionPane.showMessageDialog(null, receivedText);
}
}
private void sendData(){
byte[] dataToSend = String.valueOf(intToSend).getBytes();
DatagramPacket packet = new DatagramPacket(dataToSend, dataToSend.length, destAddr, port);
try {
socket.send(packet);
} catch (IOException e) {
e.printStackTrace();
}
}
private void createSocket(){
try {
socket = new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
}
public static String getIp() throws IOException{
URL whatismyip = new URL("http://icanhazip.com");
BufferedReader in = new BufferedReader(new InputStreamReader(whatismyip.openStream()));
return in.readLine();
}
private String getDestIp() {
String temp;
o.println("What is the other user's ip?");
temp = s.nextLine();
return temp;
}
}
This code works for me. If I input the target IP as the local machine's IP then I get the popup. If I input another machine on the network I also get the popup. My guess would be that either one of your machines has a firewall running that is blocking the incoming UDP packet, or your machines have multiple network interfaces and the IP you detect is not the one that is on the same network as the other machine.
In the former case you can disable the firewall (not a good idea if your machines are not behind a router with a firewall or are on a network which you don't have full control over) or open the specific port for incoming and outgoing UDP on both machines.
In the latter case you want to look out for the IPs presented on both machines being on the same subnet (the first three numbers being the same in the case if IPv4) e.g. both starting with 192.168.1. or similar.
When you do get your packet through you will probably get a very long popup window because you allocate a 1024 byte array and put the string at the start of that array but then convert the entire 1024 byte array into a string which may include various stuff off the end of the first N bytes you wrote the int into.
There are various ways to resolve that but this but a simple way to be able to pack a bunch of data into a packet and then read it back reliably is to use ByteArrayInput/OutputStreams and DataInput/OutputStreams:
//Sending side
ByteArrayOutputStream bout = new ByteArrayOutputStream();
DataOutputStream dout = new DataOutputStream(bout);
dout.writeInt(N); //this will write 4 bytes
byte[] packetData = bout.toByteArray();
//Receiving side
byte[] packetBuffer = ...;
ByteArrayInputStream bin = new ByteArrayInputStream(packetBuffer);
DataInputStream din = new DataInputStream(bin);
int N = din.readInt(); //This will read only the first 4 bytes, and use the same marshalling as DataOutputStream to produce a consistent value, even if the integer value is something exceptional like infinity or NaN.

UDP communication between Java and C#

I'm trying to communicate a Java program with a C# one but it's not working.
The code is really basic, here it is:
This is the Java client
static InetAddress ip;
static int port = 10000;
public static void main(String args[]) {
try {
ip = InetAddress.getByName("127.0.0.1");
DatagramSocket socket = new DatagramSocket(port, ip);
byte[] sendData = new byte[1024];
sendData = "Hola".getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, ip, port);
socket.send(sendPacket);
socket.close();
} catch (Exception e) {
}
}
And here it is the C# server
static UdpClient client;
static IPEndPoint sender;
void Start () {
byte[] data = new byte[1024];
string ip = "127.0.0.1";
int port = 10000;
client = new UdpClient(ip, port);
sender = new IPEndPoint(IPAddress.Parse(ip), port);
client.BeginReceive (new AsyncCallback(recibir), sender);
}
static void recibir(IAsyncResult res){
byte[] bResp = client.EndReceive(res, ref sender);
//Convert the data to a string
string mes = Encoding.UTF8.GetString(bResp);
//Display the string
Debug.Log(mes);
}
The c# server is a Unity file, I mean, I execute it from Unity, so Start is the first method called.
I would like them to communicate through port 10000 (or any ohter one) in my computer, java's main and c#'s start seem to be executed but the callback is never called.
Any ideas of why it isn't working? Thank you all.
BeginReceive() is non-blocking. Your program terminates before it can receive anything. Either use Receive() or put a busy-waiting-loop at the end of the server code.
I've solved it, in the Java client new DatagramSocket() must be called without any argument, and in the c# server new UdpClient(port); must be called only with the port.

Why does UDP part of RTSP client/server work locally but not remotely? [Java]

I made a simple RTSP program (Client and Server) in java to stream audio from an input device to a single client. I tried it locally and it works fine. Then I tried a remote client test and it fails. The the ServerSocket accepts the remote client connection and I can see/get the remote IP using the getInetAddress() method but the UDP part of the program seem to not work as expected.
Here is my code.
Code listing-1: RTSPServer.java
//imports go here
public class RTSPServer {
public static void main(String args[]) {
RTSPServer server = new RTSPServer();
try {
server.connect(9091);
} catch (IOException ex) {
Logger.getLogger(RTSPServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void connect(int port) throws IOException{
try (ServerSocket listener = new ServerSocket(port)) {
while (true) {
try (Socket clientSocket = listener.accept()) {
//--------RTSP starts tests here---------
//--------RTSP ends tests here---------
//--------UDP streaming starts here---------
System.out.println(clientSocket.getInetAddress());//print the IP address for debugging purpose
DatagramSocket RTSPsocket = new DatagramSocket(8300); //socket for send and receive
RTSPsocket.setSoTimeout(800);//timeout set # 800ms because ping from VPN server to home > 680ms
DatagramPacket udpPacket;
//InetAddress ClientIPAddr = InetAddress.getLocalHost();//getLocalHost version works locally
InetAddress ClientIPAddr = clientSocket.getInetAddress();//getInetAddress doesn't work locally and remotely
//InetAddress ClientIPAddr = clientSocket.getLocalAddress();//getLocalAddress only works locally
AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 44100, false);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
TargetDataLine targetLine = (TargetDataLine)AudioSystem.getLine(info);
targetLine.open(format, 40000);
targetLine.start();
byte[] data = new byte[targetLine.getBufferSize()/5];
while(true){
targetLine.read(data, 0, data.length);
RTPPacket rtpPacket = new RTPPacket(0, 0, 0, data, data.length);//make an RTP packet out of the targeLine data
//retrieve the packet bitstream and store it in an array of bytes
byte[] packetBytesArray = new byte[rtpPacket.getlength()];
rtpPacket.getpacket(packetBytesArray);
//send the RTP packet over the UDP socket using datagram packet
udpPacket = new DatagramPacket(packetBytesArray, packetBytesArray.length, ClientIPAddr, 8550);
RTSPsocket.send(udpPacket);
}
} catch (LineUnavailableException ex) {
Logger.getLogger(RTSPServer.class.getName()).log(Level.SEVERE, null, ex);
}
//--------UDP streaming ends here---------
}
} catch (IOException ex) {
Logger.getLogger(RTSPServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Code listing-1: RTSPClient.java
public class RTSPClient {
//imports go here
private Socket clientSocket;
private int port;
private String address;
public static void main(String argv[]) throws Exception
{
RTSPClient client = new RTSPClient("my.ip.address.here",9091);
client.connect();
}
public RTSPClient(String address, int port){
this.port = port;
this.address = address;
}
public void connect() throws IOException {
clientSocket = new Socket(address, port);
DatagramSocket udpSocket = null; //socket for send and receive
DatagramPacket udpPacket; //UDP packet used to receive packet
int RTSP_RCV_PORT = 8550; //receiving port for UDP/RTSP
byte[] buf = new byte[8000]; //buffer used to store data received from the server
try{
udpSocket = new DatagramSocket(RTSP_RCV_PORT);
udpSocket.setSoTimeout(40);//socket timeout 40ms
}
catch (SocketException ex)
{
System.exit(0);
}
//--------RTSP starts tests here---------
//--------RTSP ends tests here---------
//--------UDP streaming starts here---------
AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 44100, false);
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
SourceDataLine sourceLine = null;
try {
sourceLine = (SourceDataLine)AudioSystem.getLine(info);
sourceLine.open();
} catch (LineUnavailableException ex) {
Logger.getLogger(RTSPClient.class.getName()).log(Level.SEVERE, null, ex);
}
if(sourceLine != null){
sourceLine.start();
boolean makeMeLoop = true;
while(makeMeLoop){
udpPacket = new DatagramPacket(buf, buf.length);
try{
//* receive the DP from the socket:
udpSocket.receive(udpPacket);
//* create an RTPpacket object from the DP
RTPPacket rtp_packet = new RTPPacket(udpPacket.getData(), udpPacket.getLength());
//* print important header fields of the RTP packet received:
System.out.println("Got RTP packet");
//* get the payload bitstream from the RTPpacket object
int payload_length = rtp_packet.getpayload_length();
byte [] payload = new byte[payload_length];
rtp_packet.getpayload(payload);
sourceLine.write(payload, 0, payload.length);
}
catch (InterruptedIOException ex){
System.out.println("Nothing received");
}
catch (IOException ex) {
System.out.println("Exception caught: "+ex);
}
}
}
clientSocket.close();
}
}
Since the classes are huge I only left the part of the code that is necessary to troubleshoot the program.
How I've done my remote client test
I ran both code on the same physical machine but the client ran on a virtual machine connected to a VPN proxy. I increased the socket timeout for the RTSPServer's UDP socket because the ping between the VPN server's location and a test server near my location (speedtest.net) was close to 700ms (I am not sure if doing that was relevant).
When I connect the remote client to the server the server gives me the remote client's IP address (same address as given in whatismyipaddress.com). So the client is actually connected to the server. But when it comes to send the audio stream, I only get Nothing received messages. Also my computer can be accessed remotely (obviously because the client was able to connect to the server) and every port should be "visible" outside of my LAN (web server can also be accessed, and so on for every ports I've tried).

Categories