I'm doing a project for the university. The application that I´m doing is a UDP and TCP Client/Server in Java and we have to measure the time that takes send some data. The question that I have, is the following one:
To make the app faster, I would like to know if there is any way to send random data in a buffer, I mean, I do not want to use one of my files in my computer, I just want to send for example 500 bytes of data, but I do not mind what. I know you can to do it from the terminal in Linux directly, or with Iperf, but I do not know how to implement that in my Java app.
I'll answer the first question, having no idea about MTU and MSS.
To create random data and send it, you simply have to use the following:
Random random = new Random();
byte[] data = new byte[500];
random.nextBytes(data); // fill with data
try (OutputStream out = ...) {
out.write(data);
}
Related
i'm trying to learn more about networking so i decided to do a small project using sockets. I have already been successful is creating an echo server which i know is pretty basic.
The next step would be to send all kinds of files (text files, images maybe even videos?) from the server to the client and vice versa. I have been trying to do so with FIleOutputStream, ObjectOutputStream (and input obviously) and i even tried Byte Buffer but by reading the Java docs i'm starting to understand that i really dont know much about Data....
so my questions are:
Can I convert all type of data (text, images, videos) into bytes, send it and then convert it all into the data that it used to be, or do i need a specific function for each type of data?
Can I convert a text file or an image into an Object and then send it with ObjectOutputFile? If so then how can i decompress it in the other side? I've tried ObjectOutputFile.readObject but i dont really know what to do after that.
Here's what I've been trying to do (I won't post all the code because, only this particular part is important i believe:
Server: (out is a DataOutputStream)
ObjectOutputStream oos = new ObjectOutputStream(out);
Path path = Paths.get("stuff/Folder.jpg");
byte[] data = Files.readAllBytes(path);
oos.write(data);
client (in is a DataInputStream):
ObjectInputStream ois = new ObjectInputStream(in);
ois.readObject();
Thanks for all the help in advance, if you think that you know an article or a tutorial that would help me learn more about this it will also help!
Can I convert all type of data (text, images, videos) into bytes, send it and then convert it all into the data that it used to be?
Sure.
Or do I need a specific function for each type of data?
That's not an "or" - if you want to convert several types of data into bytes yourself, then you probably need a separate function for each type. Note that if you are sending files, you don't need any conversion because the content of a file is already just bytes.
Can I convert a text file or an image into an Object and then send it with ObjectOutputFile?
You could send it with ObjectOutputStream.
If so then how can i decompress it in the other side?
With ObjectInputStream.
I've tried ObjectOutputFile.readObject but i dont really know what to do after that.`
There is no such method in Java as ObjectOutputFile.readObject.
it is pretty certain that you can convert any data into bytes. However, the problem is how you could convert it back? Typically, we use Base64 encoder to encode image and when clients get that we can convert it back by Base64 decoder. There is a lot of way to do this. Please Google it.
Yes, you can use Object data to send. You may need to define a new class for the object and then call data back by getter. In client side, you need to declare the Object value as ois.readObject(). Like:
Object object = ois.readObject();
Just add a little bit advice, I feel you are not so familiar with socket right now. So, a text book like Computer Networking(Kurose Ross) will be helpful. Also, if you plan to transmit data between C and Java, then you cannot use Object because C does not support it natively.
Basically I am doing some networking with a client and server sending "packets" back and forth to each other. I have it working with basic variable data such as ints or strings passing back and forth, however now I want to pass an object.
So I know I have to serialize the data of the object to pass it through the socket. That is working as well (as I can get the correct information if I serialize then de-serialize right away) but the problem comes in when my server receives a packet.
My server interprets packet data based on the first 2 characters of the packet. So 01foobar is a type of packet correlating to whatever "01" is assigned to and 02foobar is a different packet as well. So I don't know the best way to do this with an object attached. What is mean is this...
The way I have tried to do it right now is, serialize my object and get it's string. Then append on 03 to the front. So basically I have a string that looks like 03[B#3e9513b7 (or whatever) then do getBytes() on that string which gives me another byte[] (so I can send it through the socket). Then when the server receives that information, I can append the 03 off and I'm left with just [B#3e9513b7. The problem is, [B#3e9513b7 is now a string, and not a byte[] and in order to deserialize I need to send it the same byte[] as it gave me when it serialized that data. So that got me looking into a way to make [B#3e9513b7 BE the byte[] (aka, so when I do toString() on that new byte[] it returns [B#3e9513b7) but was having issues assigning it like that because it would give me a new byte[] for [B#3e9513b7 as a string. So obviously then, when I send it to be deserialized it has a byte[] that it doesn't know what to do with and throws an error.
So I have to imagine there's a better way to do this, and I'm just making things more complicated than they should be. Any recommendations? I can provide code snippets if needed.
Thanks guys!
Edit: I guess I should mention that I am using Java with using UDP sockets.
If you are looking for a reliable and efficient solution for client-server communication, I would suggest to look at Netty.
Regarding how to serialize/deserialize your objects, you have many choices as Java serialization, XML, JSON ...
You would have to pass your serialized objects in UDP datagrams. However, be aware that UDP datagram size is limited. If you're exchanging big objects, you may want to switch to TCP transport which is more reliable.
You may also want to look at SOAP/REST web services.
Hope everyone of you doing great.I really need your help.My scenario is given below.
1-I am getting a continuous data (byte array[]) from my camera .
2-Now sending those byte[] through UDP but i have to halve that array because i can't send that big array. (P.S i can't use JMF as its not supported at my device(server side) so have to send byte[] manually through UDP)
3-I am receiving those byte [] chunks at client side.
Now i have following requirement.
-I want a player at the client side which plays my these byte [] chunks but in continuous way.(At client side i can use JMF)
Now i don't know how should i combine all these byte[] chunks at client side so that my video gets play continuously.
Please help as you guys always do.
Best regards
ZB
As an option, you may consider vlcj for video streaming.
Examples how to stream media from camera with VLC player, which may be also of some interest.
If you are transmitting over UDP I assume you are aware of the standard caveats regarding ordering and dropped packets.
I would send the data in the following fashion.
Define a datagram format which has a header and payload with the header being something quite simple like
<packetnumber><timestamp><payloadlength>
<payload>
So you'd create you chunk which is an array of bytes, calculate the payload length, current packet number and timestamp before appending the chunk. Then transmit the whole array and when it's received you can remove the packet number, timestamp and use the payload length to retrieve the data.
Then load the payload into buffer. I'd be tempted to create an object which has the packet number as a key and an array of bytes, then have a doubly linked list of these objects as the buffer. You use the packet number to see where to insert into list and to play back you just keep getting the object with the lowest packet number.
You'll need to define some control data for packet number reseting etc and flow control.
I may have made this more complex by ignoring common libraries but this is the logic I'd follow.
This is the situation:
I'm working on a project where I need to be able to send one or more images once in a while to/from the server as well as a lot of other types of data represented with text. The way it is currently done, is by sending a message with that says "incoming image of size x to be used as y" (It's not "formulated" that way of course), and then I call a method that reads the next x bytes through a DataInputStream. At first I met some problems with latency screwing things up, but I made the server spawn a new thread to send the "incoming image" message, and then wait for a flag that is set when the client responds with a "I'm ready for the image" message. It works in a way now, but if anything else, for instance a chat message, is sent while the image is being transfered, that message meant for a BufferedReader will be read as raw bytes and used as part of the image. So I will have to block all outgoing data (and add it to a queue) when there is an image that is being sent. But this seems very wrong and annoying, as users of the application will not be able to chat while receiving/ uploading a big image.
This is what I need:
So, I either need to set up an independent channel to use for raw data. Which, as far as I understand from some tinkering, I will have to set up a new socket over a new port, which seems unnecessary. The other way I can see to solve this, would be to somehow use tag each packet with a "this is text/raw data" bit, but I have no idea how to do this with java? Can you add information to the packet-header when you write something to the stream (that every packet containing that info will contain) and then read the packet data on the other end and act accordingly?
As you can see, I do not have much experienced with networking, nor have I used Java for a long time. This is also my first post here, so be kind. If anything was unclear, please ask, and I'll specify. All ideas are welcome! (There is possibly a standard way to do this?)
Thanks a lot!
There is nothing in TCP protocol itself that can help you.
You either open a new socket connection (can be to the same server port), or you split your images in, smaller chunks and wrap these chunks in envelopes saying what type of message it is: image or chat. And then reconstruct the image on the receiving end from these chunks. But this will waste bandwidth and add complexities of its own (e.g. how big do you make a chunk of that image?).
I would go with the separate binary data connection.
Java should have a standard support for HTTP protocol - use HTTP to do your picture transfers as you can set the type of data being transmitted in the header. Basically, you would have your client/server architecture establish a separate request for each new data transfer (be it text or image), that way enabling you to do processing in a simple loop.
This might be of some help to you : How to use java.net.URLConnection to fire and handle HTTP requests?
I am currently working on a homework assignment and I am thoroughly stuck. I am on the last question and I just can not figure out how to go about accomplishing the last task. Below is the tasks I had to complete:
The client should
save the file in the "client"
subdirectory of the home directory.
Test your program. Be sure it works
with binary files, not just text
files. Be sure it works when both
programs are on the same machine as
well as when they are separated over
the network.
Thus far when I start the server it asks what port I want to use. Then I start the client and it asks what IP and port to use. The the server immediately sends a list of the files in the home directory "server" folder. I then respond with the client with the file number I wish to download. This is where I get stuck. I can't seem to find any information about how to do this. So as you can see in my code posted below, I am trying to use a FileInputReader to convert the file to an array of bytes. Then I am sending that to the client. I am then trying to FileOutputReader the recieved array of bytes to a file. But I can't seem to find the correct methods to do that, or even if I am doing that correctly.
CLIENT
int i = 0;
while(i < 1000){
String modifiedSentence = inFromServer.readLine();
System.out.println("From Server: " + modifiedSentence);
i++;
}
while(j < 1000) {
int byteString = inFromServer.read();
ArrayList<byte[]> bytes = new ArrayList<byte[]>();
bytes.add(byteString);
}
Integer byteInt = new Integer(byteString);
FileOutputStream fo = new FileOutputStream(System.getProperty("user.home")+ "/client/text.txt");
fo.write(byteInt.byteValue());
}
}
SERVER
byte[] bytes = new byte[1024];
FileInputStream fi = new FileInputStream(file.toString() + fileArray[userChoiceInt]);
fi.read(bytes, 0, 1024);
outToClient.write(bytes, 0, 1024);
}
}
}
If anyone could offer any advice or the correct classes or methods to use I would appreciate it.
Thank you in advance.
Without spoiling the whole thing here's some hints.
This can be easily accomplish by using Socket (Server & Client). Using byte[] for transfering the file(s) will ensure that your program will work with both ascii and binary file(s).
Another approach would be to use the build in Remote Method Invocation (RMI). I haven't transfered file using this approach but I'm sure it's feasible.
And in case you didn't know, getting the user home directory is accomplished with the following call: System.getProperty( "user.home" );
You can take a look at this tutorial by Sun (Oracle). That should give you a basic understanding of sockets.
What I do seem to notice however, in the client side, you iterate a specific amount of times (1000) which is not a good idea since generally, you do not know the size of the file to be sent, the tutorial should show this and how to make the appropriate changes. Also, you keep creating the structures within the loop, so you loose any information that you have received, besides creating new datastructures each and every time, which is inefficient.
What you have to do is to move the initialization of the structures from outside the loop. Also, in the case of the modifiedSentence variable, you might want to change it from string to StringBuilder.
If you can use an IO library for this, I would suggest Netty or Mina. There are some netty examples here: http://jboss.org/netty/documentation.html
Even if you cannot use a library, these may be helpful for learning how things are done.
You probably should not ask how to do homework in the class on Web sites like this. It is not appropriate. Your server does look mostly good. Your program will only read files up to 1024 bytes though. You should look at java.io.File in more detail. There is a length method you can use to find the length of the file, so you know how much to send.