I'm trying to send doubles from Matlab(Simulink) to java.
This is my code:
public static void main(String[] args) throws SocketException, UnknownHostException, IOException {
DatagramSocket socket = new DatagramSocket(25000);
byte[] buf = new byte[512];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
while (true) {
socket.receive(packet);
String msg = new String(buf, 0, packet.getLength());
Double x = ByteBuffer.wrap(buf).getDouble();
System.out.println(x);
packet.setLength(buf.length);
}
}
I'm getting values but they really don't make sense...
Most likely you are sending doubles as little-endian but ByteBuffer assumes "network order" which is big-endian.
try
DatagramSocket socket = new DatagramSocket(25000);
byte[] buf = new byte[512];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
DoubleBuffer db = ByteBuffer.wrap(buf).order(ByteOrder.LITTLE_ENDIAN).asDoubleBuffer();
while (true) {
socket.receive(packet);
db.limit(packet.getLength() / Double.BYTES);
double x = db.get(0);
System.out.println(x);
}
Note: UCP is lossy, so some packets will be lost.
Related
I'm reading and writing bytes on an open socket. This is my code.
#Test
public void testSingleRequest() throws IOException {
Server server = new Server(9000, 100);
new Thread(server).start();
Socket clientSocket = new Socket("localhost", 9000);
DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream());
String payload = "a";
byte[] load = buildPushPayload(payload);
out.write(load);
DataInputStream in = new DataInputStream(new BufferedInputStream(clientSocket.getInputStream()));
byte[] buffer = new byte[128];
for (int i = 0; i <128 ; i++) {
int read = in.read(buffer, 0, 128);
}
out.close();
server.stop();
assertEquals(0, buffer[0]);
Since I'm reading a fixed length, I believe the for loop shouldn't block, but it still does. How do I get the loop to unblock?
Have a homework to create client code to send a string split into 2 variables over UDP. Server receives and confirms by sending back the two split variables back to front.
For some reason my response is blank when I run it and not sure why.
can anyone help please?
When I try doing it with integers on another code it works but when I try do strings nothing comes back.
Client code:
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class UDPClient
{
public static void main (String[] args) throws Exception
{
DatagramSocket client = new DatagramSocket();
InetAddress IPAd = InetAddress.getByName("localhost");
byte [] sendData1 = new byte[1024];
byte [] sendData2 = new byte[1024];
byte [] receiveData = new byte [1024];
String input = "";
Scanner in = new Scanner (System.in);
System.out.println("Enter word: ");
input = in.nextLine();
String [] splitWord = input.split("");
int length = splitWord.length;
int evenSplit = 0;
int oddSplit = 0;
String firstHalf = "";
String secondHalf = "";
if (length%2==0)
{
evenSplit = length / 2;
for (int i=0; i<evenSplit; i++)
firstHalf += splitWord[i];
for (int i=evenSplit; i<length;i++)
secondHalf += splitWord[i];
}
else{
oddSplit = (length+1)/2;
for (int i=0; i<oddSplit;i++)
firstHalf += splitWord[i];
for (int i=oddSplit; i<length;i++)
secondHalf += splitWord[i];
}
sendData1 = firstHalf.getBytes();
sendData2 = secondHalf.getBytes();
DatagramPacket sendPacket1 = new DatagramPacket (sendData1,
sendData1.length, IPAd, 2000);
DatagramPacket sendPacket2 = new DatagramPacket (sendData2,
sendData2.length, IPAd, 2000);
client.send(sendPacket1);
client.send(sendPacket2);
DatagramPacket receivePacket = new DatagramPacket (receiveData,
receiveData.length);
String serverReply = new String (receivePacket.getData());
System.out.println ("From server: " + serverReply);
client.close();
}
}
Server code:
import java.io.*;
import java.net.*;
public class UDPServer
{
public static void main (String [] args) throws Exception
{
DatagramSocket server = new DatagramSocket (2000);
byte [] receiveData1 = new byte[1024];
byte [] receiveData2 = new byte[1024];
byte [] sendData = new byte [1024];
while (true)
{
DatagramPacket receivePacket1 = new DatagramPacket
(receiveData1, receiveData1.length);
server.receive(receivePacket1);
DatagramPacket receivePacket2 = new DatagramPacket
(receiveData2, receiveData2.length);
server.receive(receivePacket2);
String firstHalfWord = new String (receivePacket1.getData());
String secondHalfWord = new String (receivePacket2.getData());
InetAddress IPAd = receivePacket1.getAddress();
int port = receivePacket1.getPort();
String response = secondHalfWord + firstHalfWord;
sendData = response.getBytes();
DatagramPacket sendPacket = new DatagramPacket (sendData,
sendData.length, IPAd, port);
server.send(sendPacket);
}
}
}
If I type hello it is mean to reply with lohel (hel + lo back to front)
it simply comes back with "From server:" without any string response.
Before the line String serverReply = new String(receivePacket.getData()); you need to say client.receive(receivePacket);
I have two (client - server - client) system. First one uses TCP and second one uses UDP. It is interesting that my TCP using system is faster than UDP using one when transferring files in size 5-6 mb. Does problem occurs because of my coding mistakes or can that happen?
TCP Client
try {
socket = new Socket("localhost", 7755);
} catch (Exception e) {
System.out.println(e.getMessage().toString());
}
out = new PrintWriter(socket.getOutputStream(), true);
int i = 0;
while (file.hasNext()) {
String line = file.nextLine();
if (!line.isEmpty()) {
out.println(line);
}
i++;
}
TCP Server
try {
serverSocketA = new ServerSocket(7755);
serverSocketB = new ServerSocket(7760);
} catch (Exception e) {
System.out.println("Port error!");
}
System.out.println("Server is ready...");
clientSocketA = serverSocketA.accept();
clientSocketB = serverSocketB.accept();
PrintWriter out = new PrintWriter(clientSocketB.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocketA.getInputStream()));
while((dataFromClientA = in.readLine()) != null) {
out.println(dataFromClientA);
}
UDP Server
private static byte[] buf = new byte[6];
static Scanner file;
public static void main(String[] args) throws IOException{
long startTime = System.currentTimeMillis();
socket = new DatagramSocket();
address = InetAddress.getByName("localhost");
file = new Scanner(new File("sentfile.txt"));
DatagramPacket packet;
while (file.hasNext()) {
String line = file.nextLine();
if (!line.isEmpty()) {
buf = line.getBytes();
packet = new DatagramPacket(buf, buf.length, address, 7765);
socket.send(packet);
}
}
UDP Client
private static byte[] buffer = new byte[6];
private static byte[] buffer2 = new byte[6];
private static boolean running;
static PrintWriter writer;
public static void main(String[] args) throws IOException {
udpSocketB = new DatagramSocket();
address = InetAddress.getByName("localhost");
udpSocketA = new DatagramSocket(7765);
running = true;
DatagramPacket packet;
while(running) {
packet = new DatagramPacket(buffer, buffer.length);
udpSocketA.receive(packet);
InetAddress address = packet.getAddress();
int port = packet.getPort();
packet = new DatagramPacket(buffer, buffer.length, address, port);
String received = new String(packet.getData(), 0, packet.getLength());
DatagramPacket packetToB;
buffer2 = received.getBytes();
packetToB = new DatagramPacket(buffer2, buffer2.length, address, 7770);
udpSocketB.send(packetToB);
if (received.equals("end")) {
running = false;
continue;
}
}
I just add client1 and server codes and rest is similar. What could be the reason?
When you write over a TCP socket, it will coalesce bytes if possible into an MTU of data of around ~1500 bytes making the overhead of the packet header relatively small.
When you write each line in its own UDP packet it has an overhead for each line, possibly more than the actual data sent.
Note: in neither case do you need to read a line at a time. You can read say a byte[] of 1 KB at a time and print that.
public class TCPClient {
public static void main(String[] args) throws IOException {
try (Socket socket = new Socket("localhost", 7755);
FileInputStream fis = new FileInputStream(args[0])) {
byte[] bytes = new byte[1024];
OutputStream out = socket.getOutputStream();
for (int len; (len = fis.read(bytes)) > 0; ) {
out.write(bytes, 0, len);
}
}
}
}
public class TCPServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(7755);
System.out.println("Server is ready...");
try (Socket socket = serverSocket.accept()) {
byte[] bytes = new byte[1024];
for (int len; (len = socket.getInputStream().read(bytes)) > 0; )
System.out.write(bytes, 0, len);
}
}
}
You can do the same thing with UDP, transfering 1 KB at a time and get a similar throughput.
NOTE: UDP is lossy, so you might lose packets, or get them out of order.
TCP has been heavily optimized by some of the greatest networking experts in the world. It's specifically designed for sending streams of data over IP networks as quickly and efficiently as possible. It's tied into the kernel and they are heavily optimized as a unit on most modern platforms. You're not going to outperform it unless it does something that you don't need and you can obtain a significant benefit from not doing that thing.
I have a problem to send a file to a group of users. Users could receive the file was sent from server but the file would not be saved if it is less than 8kb.
Here is the code:
MulticastSocketServer
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class MulticastSocketServer{
public static void main(String[] args) {
String fileName;
String address = "235.0.0.1";
int port = 2222;
Scanner in = new Scanner(System.in);
System.out.print("Please enter file name : ");
fileName = in.next();
try (DatagramSocket serverSocket = new DatagramSocket()) {
InetAddress addr = InetAddress.getByName(address);
BufferedReader br = new BufferedReader(new FileReader(fileName + ".txt"));
DatagramPacket fn = new DatagramPacket(fileName.getBytes(),fileName.getBytes().length, addr, port);
serverSocket.send(fn);
DatagramPacket msgPacket = null;
String txt = "";
while((txt = br.readLine())!=null){
msgPacket = new DatagramPacket(txt.getBytes(),txt.getBytes().length, addr, port);
serverSocket.send(msgPacket);
System.out.println(txt);
}
}catch (IOException ex) {ex.printStackTrace();}
}
}
MulticastSocketClient
import java.io.*;
import java.net.*;
public class MulticastSocketClient {
public static void main(String[] args) throws UnknownHostException {
int port = 2222;
String address = "235.0.0.1";
InetAddress addr = InetAddress.getByName(address);
byte[] buf = new byte[64];
byte[] buf2 = null ;
try (MulticastSocket clientSocket = new MulticastSocket(port)){
clientSocket.joinGroup(addr);
DatagramPacket fn = new DatagramPacket(buf, buf.length);
clientSocket.receive(fn);
String name = new String(buf, 0, buf.length);
String fileName = name.trim();
try(PrintWriter pw = new PrintWriter(new FileWriter(fileName+"2.txt"))){
while (true) {
buf2 = new byte [1024];
DatagramPacket msgPacket = new DatagramPacket(buf2, buf2.length);
clientSocket.receive(msgPacket);
String msg = new String(buf2,0,buf2.length);
String txt = msg.trim();
pw.println(txt);
System.out.println(txt);
}
}catch(FileNotFoundException ex){ex.printStackTrace();}
} catch (IOException ex) {ex.printStackTrace();}
}
}
You're never exiting the while (true) loop, because you don't have any mechanism for transmitting end of stream, so you're never closing the PrintWriter, so it isn't flushing its final buffer, so any file < 4096 chars won't get flushed at all, so it will be zero length.
However your code has much worse problems that this. You are assuming:
the filename fits into 1024 characters
every line of the input file fits into 1024 bytes
the filename is received first
all the content packets are received
all the content packets are received in order
all the content packets are received exactly once
the length of every datagram is 1024
the data is text, not binary, and can be converted losslessly to a String
You're using UDP. That means that most of these assumptions are invalid.
I'm new to multithreading. Im trying to do sending of messages between a client and a server. When I send a message to the server, my output in the server is supposed to be "Aji Computer: Thanks! :D", but instead I get a truncated data "Aji Computer: Thank".
Server code
public QuoteServerThread(String name) throws IOException {
super(name);
socket = new DatagramSocket(4445);
byte[] buf = new byte[256];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
in.close();
socket.receive(packet);
String dString = "Wassup " + packet.getAddress().getHostName() + "!";
//if (in == null) dString = new Date().toString();
//else dString = getNextQuote();
buf = dString.getBytes();
InetAddress address = packet.getAddress();
int port = packet.getPort();
packet = new DatagramPacket(buf, buf.length, address, port);
socket.send(packet);
//THIS IS WHERE IM SUPPOSE TO PRINT "Aji Computer: Thanks! :D". But it prints out wrongly
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
String received = new String(packet.getData(), 0, packet.getLength());
System.out.println(received);
socket.close();
Client code
DatagramSocket socket = new DatagramSocket();
byte[] buf = new byte[256];
InetAddress address = InetAddress.getByName("Aji Computer");
DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 4445);
socket.send(packet);
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
String received = new String(packet.getData(), 0, packet.getLength());
System.out.println("Server: " + received);
//THIS IS WHERE I SENT MY "Aji Computer: Thanks! :D" PACKET TO SERVER.
buf = new byte[256];
String str = "Aji Computer: Thanks! :D";
buf = str.getBytes();
packet = new DatagramPacket(buf, buf.length, address, 4445);
socket.send(packet);
socket.close();
}
Just to let you know, this code is from Oracle. I modified a bit so that I would know how it works.
You reassign the size of your byte array from 256 bytes to: buf = dString.getBytes(); And further down in the program you created a new packet to receive on using packet = new DatagramPacket(buf, buf.length); This uses the length of dString.getBytes() instead of byte[256] I am assuming that dString.getBytes() has less space than "Aji Computer: Thanks!"
Try reassigning your byte array to its original value:
buf = new byte[256];
EDIT: removed 'byte' from above