Client & Server java programs. How to detect the end of a transmission - java

I have a client program and a server program. I send 512-byte packets, and I want to send some files. How can the server know when the transmission is finished?
I want the server program to receive some files before it stops running, and I want to distinguish between them. What I want to do is print out the number of packet received:
Packet number 1 has been received
Packet number 2 has been received
.
.
Packet number N has been received
And once I receive this file, I want to set this counter variable to 0, which means that I have to detect when a file is completely sent (it means to receive less than 512 bytes). Is there any way to count the amount of bytes received from the client program? Which is the best way to do it? I am using byte arrays.

The best way to do it is to introduce a delimiter. This will become part of your protocol.
When you're sending the files, you send the data. When there are no more bytes to sends, the client will send an END_OF_MESSAGE value to the server, indicating that there is no more data to send, then in your code, you've got something like:
String END_OF_MESSAGE = "ENDOFMESSAGE";
if(input.equals(END_OF_MESSAGE)) {
// You know the client has finished their transmission.
}
NOTE: I would make the value of END_OF_MESSAGE far more complex than that. This is simply for demonstration purposes.
EDIT
As JB Nizet suggested, another option is to send the length of the file before anything else. That way the server knows when the transmission is finished when the amount of transferred bytes are equal to, or greater than, the pre-set size.

Related

I am using UDP Socket programming in java and need to send data over a noisy bridge

I am using UDP Socket programming in java and need to send data over a noisy bridge.What i have done till now is the client is sending the message to servery but as i told the bridge contains some noisy so what should i do to send successfully message. I am giving code of Bridge. Can anybody help.Thanks in advance
In short, I would
Send a negative acknowledgement when a gap in the sequence numbers is sent.
I would resend much more often, up to the point that the line saturates. Possibly resend after 100 ms or less.
If the data is short, I send two pieces of data in a packet to increase the chances of it getting through.
I would send an acknowledgement which implies that a range of values are acknowledged e.g. everything up to that point, for cases where the acknowledgement is corrupted.

Implementing a client for custom TCP protocol

I have to implement a client for communication with the server by custom protocol based on XML format. This is an application layer protocol, based on TCP. So, my client sends a request XML message and receives a response, also XML message. Now, I consider how to be ensured that I received whole mesage before I start parsing it.
I see two aproaches:
Receiving bytes to the some magic number that means end of message.
It is the best approch (for my eye), yes?
But, it is possible that there is no magic number and size of message is not known. What about that case? I saw some clients for other protocols and I see something like that.
while(true){
r = socket.read(buffer, offset, 1024);
if(r < 1024) break;
offset += r;
}
// parse buffer
and I am not sure whether it is ok. It assumes that if we read less than 1024 bytes then the messae is completed. Is it ok?
What is a recommend way to solve it?
In your custom protocol you need to include the steps below :
Client
Calculate number of 1024 byte chunks of the XML contents i.e ceiling(XML content bytes /1024)
Send the number of step 1 to the server through the socket
Transmit the contents in chunks of a defined buffer size e.g 1024 bytes
Server
Read number of chunks to receive from client
Inside a for loop of size equal to the number read at step 1, start receiving contents in the predifined buffer size.
This way the server knows how many bytes the actual content is before it starts receiving the XML contents.

many io stream from one socket

Can I parallelly connect many independent I/O streams of server's socket and client's socket such that each pair of I/O streams could send different data at the same time ?
How could I achieve such a connection in java without increasing number of sockets between server and client?
There's always one stream for input and one stream for output, so you can't add more streams.
However, as sje397 commented, you can use the same stream to send "different" data, you just need to come up with a way to distinguish the channels in the receiving side, so it can reconstruct the data properly. This is a protocol design issue.
Edit:
In your example you could have a packet structure with a header that tells the type (or channel) of the packet, length of the data and for the file packets some additional information if needed. Let's assume that the length field is a single byte, so your maximum packet size (for String packets) would be 1 + 1 + 255 = 257 bytes.
When the server reads bytes, it will check the first byte for the type of the packet. After determining that it's a String packet, it will read the length, then read the payload. Then the process repeats itself.
For file data additional header information is most likely needed, otherwise the non-String packets will just be a bunch of bytes.
This means that your protocol will become packet based, so you must write the data one packet at a time. Assuming that a data packet has a max size of 64K, you would then be able to send data in the following way (imagine that it's a network pipe):
Client -> 257(S) -> 64K(D) -> 257(S) -> 64K(D) -> 257(S) -> Server
allowing you to interleave the two different kinds of data in a single network connection.
Assuming that you want fast replies for console input, my suggestion to use two socket streams - one for file data and another for user input. You can use ObjectInputStream and ObjectOutputStreams to simplify your protocol. Just create a class for your protocol make it serializeable and use it with socket streams.

Java datatransfer through sockets. How to keep sender and receiver in "sync"

I want to implement a simple way to transfer Data from one client to another.
The implementation itself is not the question - it already works. I've a problem with the real transfer rate on sender side.
You all know the progress bars while you send files to another client using [put your desired chat/filetransfer program here]. You see the transferred bytes and the bytes left to transfer and maybe an estimated time until the transfer is complete. The same thing I try to implement too but it seems I've problems with the buffers in between.
While the send buffer is a nice feature - it affect the measured transfer rate to the other client enormously. Starting the transfer I get nearly infinite Bps and during the transfer the Bps reduce slowly but never get where the real transfer is.
The effect is that the sender visually finishes sending a file while the receiver still receiving bytes. This totally desync sender and receiver what I need to avoid (because of other reasons).
My first attempt sending a file was just like this (pseudo code):
while(still bytes left to read) {
Sender reading Byte-Array from InputStream (aka FileInputStream or something else)
Sender write and flushes this Byte-Array to the SocketOutputStream
}
This ends in the described situation where sender and receiver is totally desynced.
My next attempt was this:
while(still bytes left to read) {
Sender reading Byte-Array from InputStream (aka FileInputStream or something else)
Sender write and flushes this Byte-Array to the SocketOutputStream
Sender wait for ACK-Paket from Receiver
}
So the sender write the Byte-Array to the wire and wait for a small ACK-Paket from the receiver. After receiving the ACK the sender sends the next Byte-Array.
While this works as desired on slow connections (aka WAN connections to the internet) it is horrible slow on LAN connections.
I came to the conclusion that I don't like the ACK-Idea but I also don't like the desync situation.
How does other clients workaround such situations? Is there a way to disable the buffer so that outputStream.write(byte[]) just take as long as the wire need to transmit the data, or is there any other mechanism I can use to "see" how many bytes are transferred for real?
Thanks in advance
Martin
Instead of displaying what you have sent, display what the other end has told you it has received. i.e. the other end can send back the number of bytes it has received. This way your progress bar will be slightly pessimistic, rather than really optimistic.
Your problem is that you are trying to send the entire array you managed to read as a single object. On the sending side, you get a big array, call write and then flush which sends the entire array and waits for it to be flushed (with no control for you in between, so you sending app has no way to display progress). On the receiving end you get the same problem. You probably just call read which would read the entire ArrayList in a single operation.
Chances are, you are able to read a lot of data before you try to send it as a big array.
You can get some control if you break the array into reasonable "chunks" (maybe a simple max(1024, arraysize/100)). Then send the chunks one by one. The pseudo code would look like this:
chunkSize = max(1024, arraysize/100)
while(still bytes left to read) {
Sender reading chunkSize bytes into Byte-Array from InputStream
Sender write and flushes this Byte-Array to the SocketOutputStream
reportProgress()
}

SerialPort Reading in java

Here is problem in my Java Serial Communication ... my jennic hardware device is connected using UART. I want to retrieve values form my device ..
i am receiving byte array of string in SerialPortEvent.DATA_AVAILABLE
case SerialPortEvent.DATA_AVAILABLE:
try {
int size;
while(inputStream.available()!=0) {
byte buff[]=new byte[100];
size=inputStream.read(buff);
inputStream.close();
String result = new String(buff,0,size);
ZPS_tsAplZdpIeeeAddrRsp IeeRsp = new ZPS_tsAplZdpIeeeAddrRsp(result);
}
first I read the bytes and store it in buff[]. then convert it into string and convert it to string array there after .. but my problem is i get the out put like but few time its breaks.
Sample output:
80011634002078445541560000341201004189
80011635002078445541560000341201004189
80011636002078445541560000341201004189
/*Here is Break my seq */
800116370020784455
41560000341201004189/*this two breaking seq generated two separate array and here is the problem*/
80011638002078445541560000341201004189
is there problem for flushing the input buffer I have tried inputStream.reset() but it doesn't work.. can anyone give me a suitable suggestion to overcome the problem..
thanks...
The 'problem' is in your expectations. Nowhere does it say that read() will fill the buffer, or that serial data transfer will preserve your message boundaries. That's up to you. All you get is a byte stream.
You need to read from the port into a buffer, and when that buffer has a whole message, flush that portion of the buffer into your message handling routines. This means you need to define your messages in a manner where each message can independently be identified and isolated.
Reading a stream will work or block when data is available or unavailable; however, reading from a stream won't guarantee that you get your data in one message-sized pieces. You only get notice that there is data to be read. You noticed a common issue when data is available to be read in the serial port buffer, and you started reading it before all of the message was available to be read. Remember that there is another issue which can occur, perhaps during another run two or more messages might be buffered in the serial port buffers before your program is ready to read the "next" message.
Rework you communication protocol to read bytes into a buffer (a class), which holds bytes until messages are available to be read. Then put an interface on that buffer readMessage() which acts like read() except at the message level (buffering until it gets a full message).
In general you cannot expect that a "message" sent from one end of a serial connection is going to be received all as one group. You may get it all at once or in several chunks of varying lengths. It is up to your receiving program to use what it knows about the incoming data to read bytes from the serial port and put them together and realize when a complete message has been received.
Normally devices handle this in one of three ways:
Fix length packets - you read until you get X bytes and then process those X bytes.
Packet length is part of the packet header indicating how many additional bytes to read before considering the data received so far as a complete packet.
Packet start/end indicators (STX or SOH to start and ETX to end usually). You treat all data received between a start and end indicator as one message packet.

Categories

Resources