Hi I want to send a fixed amount of data (say 5MB) from server to Android client over TCP using the Java programming language. The data doesn't matter it will be dropped at the client I am only doing this to do performance measurements on the phone.
Can anyone recommend a good way of accomplishing this? How can I have the server continually sending a large amount of data? Without the intermittent behaviour of reading a line from a file, then sending those bytes... then reading another line and sending those ones.
Ideas? Cheers.
You don't need to send a file, you could just send a block of data.
// server which sends 5 MB on connection.
ServerSocket ss =
Socket s = ss.accept();
s.getOutputStream().write(new byte[5*1024*1024]);
s.close();
You could have a byte array of size 1024 and loop sending it out the socket over and over. The data doesn't need to be unique. You could use a larger array if you felt a KB isn't big enough for you.
Sounds like you were asking about the server there. Were you also wondering about the client?
Related
I have recently tried my hands over Socket Programming by creating an SSL Socket used to stream data live from a server with no success of course. When I analyze the data packets through Wireshark, I realize the size of request data has been magnified n number of times in the packet and hence the request reaches the server in fragments where as the actual JSON request is a handful of bytes and should reach the server in a single shot.
Any help would be appreciated.
Wrap a BufferedOutputStream around the SSLSocket's output stream, and don't flush it until you really gotta, which is usually not until you're about to read the reply. Otherwise you can be sending one byte at a time to the SSLSocket, which becomes one SSL message per byte, which can expand the data by more than 40x.
However:
the request reaches the server in fragments
That can happen any time. The server has to be able to cope with receiving data as badly fragmented as one byte at a time.
where as the actual JSON request is a handful of bytes and should reach the server in a single shot.
There is no such guarantee in TCP.
I have to measure the speed of UDP and TCP between a Client and a Server, for a university project, and for that we have to choose the data we will send. For example 500 bytes, 750 bytes, 1500 bytes...
In Linux I know how to reduce or increment MTU of the segment, but I do not know how to do it in Java for my application. Are there any function to do it, or a way to make the socket bigger or smaller and force it to send the amount of data that I want?
Thank you in advance!
The Java socket API is pretty high level and doesn't give you much fine grained control.
That said you can write x number of bytes to the socket then flush it.
You should also enable TCP_NODELAY, otherwise the packets may end up being buffered.
So long as the amount of bytes is less than the underlying OS MTU then the messages should be sent in separate packets.
I recently use ObjectOutputStream to write objects in TCP/IP socket programming.
If I want to write a large size of List<Object>/ArrayList<Object> through the socket
(e.g. list.size: 100, the total bytes may larger than the payload size),
should I just call writeObject(List<Object>/ArrayList<Object>)?
Is that OK, or any Exception occurs?
Does ObjectOutputStream automatically split the list to a few segments before sending the packets? Or it doesn't support?
Is there another way to send a large size of an object?
As for ObjectInputStream, can I just call readObject() to receive the large size of List<Object>/ArrayList<Object>?
Thanks in advance.
->
Another questions: Does ObjectInputStream receive anything when the list is not fully sent from the sender?
I want to close the socket but the ObjectOutputStream is still sending the list. Does it shutdown immediately when I close socket, and the list segments are destroyed?
Is that OK, or any Exception occurs?
It's ok.
Does ObjectOutputStream automatically split the list to a few segments
Yes.
before sending the packets? Or it doesn't support?
The underlying socket has no control over how packets are sent. Nor should you need it.
Is there another way to send a large size of an object?
Many but 100 isn't very large. If you had a few million of large objects it might be worth it. If you have a few billion you definitively need to consider alternatives. There is lots of alternatives but I wouldn't bother unless you need it.
As for ObjectInputStream, can I just call readObject() to receive the large size of List/ArrayList?
Yes, that is what it is for.
should I just call writeObject(List<Object>/ArrayList<Object>)?
Yes.
Is that OK, or any Exception occurs?
It is OK, but exceptions can always occur, especially over a network.
Does ObjectOutputStream automatically split the list to a few segments before sending the packets? Or it doesn't support?
Yes, and TCP does as well, and IP.
Is there another way to send a large size of an object?
Why? You have this way. You don't need another way.
As for ObjectInputStream, can I just call readObject() to receive the large size of List<Object>/ArrayList<Object>?
Yes.
everyone. I am a beginner in network programming. Currently, I want to do an experiment which sends a file(~2M bytes) from Android phone to Ubuntu server. How can I send it at the highest speed? I have tried something like using Bufferedreader in Java, reading each byte out of the file and sending that single byte to server through socket "outputstream write" function. This way seems to cost too much time. I notice that if in the same network condition, I send same file using some Immediate Messenger tools,like Skype;it is much quicker than I did. Does anybody know the API or implementation protocol beneath those Immediate Messenger software?
I probably need to call other efficient APIs other than socket? I am also trying to read the whole file into a byte array and then call "socket write" function to send the huge byte array to server for a just single time.Although when I receive it at server side to found that there are a lot of "padding zeros" distributed in my original data, the whole transfer seems to cost less time than the "single byte transfer" method. Anybody has any advice on this?Thanks a lot!
Thanks for everybody's answer. I think I just made a silly mistake. The real reason for my slow transmission using TCP socket is that every time I just read a single byte out of the file and call "void write(int b)" to send this single byte to server.This method is very time consuming. Now every time I try to read 256 bytes out of file and send these 256 bytes through "void write(byte[] b,int off,int len)";in this way, the transmission is pretty fast.Therefore, it is not the problem of TCP itself. It is my mistake of calling the wrong API. I have not tried UDP yet. But I think it is also a good choice.Thanks again,everybody.
Short of reinventing TCP/IP the fastest way to send will be via UDP, if your connection is good enough (few losses) than you on;y need to implement packet sequence so the sender prepends sequence number to the data packets, the receiver keeps track of missed packets and requests them again after all data is sent. After all data is received the receiver can reassemble the complete file.
This is simplistic implementation of TCP over UDP.
I have written a small program in Java which reads info from a serial port (some text messages and also some binary data, mixed), and then send it through a TCP socket.
At first I tried to get data into a buffer, and send everything when a '/n' arrived, but binary data doesn't work that way.
My second thought was sending the data all the time, byte by byte. But it gets too slow, and I guess I'm losing data while sending it, even thought I used threads.
Next idea would be sending data when I reach 100 bytes stored for example, but it is a dirty fix.
My serial data comes from a GPS receiver, and these devices usually send many sentences of data (text and binary) each second (or configurable to 10, 50, 100Hz, it depends of the model). Anyway, there is a gap of time where data is received, and a considerable larger gap of time when nothing is being received. I guess the fanciest way to get rid of my data would be detecting that gap and sending all the stored data then, before new data arrives when the gap ends.
How could I detect this kind of event?
EDIT: I use RXTX package to get rid of the serial port, and I'm working over Windows 7 64bits
To detegt the gap, just enable timeout with enableReceiveTimeout.
Just read and write byte[] buffers as you get them, making sure to only write the actual count returned by the read() method.