I am sending data to the server twice. First, I send "Hello world" and then I send "Server".
But the server received the data at 1 read. But the server have to read the data in a two-read operation.
Also, I write the data. Then read data from server and then I write the data.
In this case, the server can read the first data. But server can not read the second data.
The server uses read, write, read.
So how to overcome this issue? How do I write data to socket in BlackBerry?
What you describe is how TCP is supposed to work by default. What you are seeing is the Nagle algorithm (RFC 896) at work, reducing the number of outbound packets being sent so they are processed as efficiently as possible. You may be sending 2 packets in your code, but they are being transmitted together as 1 packet. Since TCP is a byte stream, the receiver should not be making any assumptions about how many packets it gets. You have to delimit your packet data in a higher-level protocol, and the receiver has to process data according to that protocol. It has to handle cases where multiple packets arrive in a single read, a single pakcet arriving in multiple reads, and everything in between, only processing packet data when they have been received in full, caching whatever is left over for subsequent reads to process when needed.
Hard to say without a little more detail, but it sounds like you're using 1-directional communication in the first case - i.e. the client writes, then writes again. There are any number of reasons that the server would receive the 2 writes as 1 read. Buffering on the client, somewhere in the wireless stack (or in the BES), buffering on the server side. All of those are legal with TCP/IP.
Without knowing anything more about your solution, have you thought about defining a small protocol - i.e. the client writes a known byte or bytes (like a 0 byte?) before sending the second write? Then the server can read, then recognize the delimiting byte, and say 'aha, this is now a different write from the client'?
As previously said this is an expected TCP behavior to save bandwidth. Note that to deliver your package TCP adds lot of data (e.g. destination port,sequence number, checksums...).
Instead of flushing the data I´ll recommend you to put more work in your protocol. For example you can define a header that contains the number of bytes to read and then the payload (the actual data).
The following code is a protocol encoded in an string with the structure [length];[data]
StringBuffer headerStr = new StringBuffer();
StringBuffer data = new StringBuffer();
//read header
char headerByte = dataInputStream.readChar();
while (headerByte != ';') {
headerStr.append(headerByte);
headerByte = dataInputStream.readChar();
}
//header has the number of character to read
int header= Integer.parseInt(headerStr.toString());
int bytesReaded = 1;
char dataByte = dataInputStream.readChar();
//we should read the number of characters indicated in the header
while (bytesReaded < header) {
data.append(dataByte);
dataByte = dataInputStream.readChar();
bytesReaded++;
}
For the first query, I guess you are using TCP. If you use UDP, then the server will read the packets in the order you want.
Can you be more clear/elaborative on the second query ?
I would try explicitly telling Connector.open to open up the stream as read_write. Then I would ensure that I flush my connections after each time I talked to the server.
SocketConnection connection = (SocketConnection) Connector.open(url, Connector.READ_WRITE);
OutputStream out = connection.openOutputStream();
// ... write to server
out.flush()
I got a solution to overcome to extract both the string
On sender device
Create a header which contains details of that data eg the data
length, datatype etc.
Add this header to the actual data and send it
On recipient device
read the header
retrieve the actual data length from the header
read the next data upto the data length as specified by the header
Related
I am using CANalyzer.
I am transmitting CAN message using Interactive Generator block. I use IG to modify signals in transmitted message by hand.
I need to automaticaly calculate checksum (the last byte in the message) every time the message is sent. Checksum is calculated from all previous data bytes in the message (message is always 8 bytes long). There is no option in IG to do that.
I need:
Set signals by hand using IG.
Automatically calculate value of the last data byte according to values of preceding data bytes.
I tried to write simple code in CAPL but without success.
I put CAPL Program node after the IG node in the Configuration window and wrote on message event in CAPL script:
on message FooMsg
{
message FooMsg msg1; // FooMsg is name of message in database
msg1 = this; // copy message from IG to temporary variable
// this.byte(7) = 0x11; // not posibble, compiler warning
msg1.byte(7) = 0x11; // constant value just for test
output(msg1); // send message
}
The message is transmitting but the Tx period set in IG is not respected (message is transmitted as fast as possible).
I thought I catch the message generated from IG, modify it and send to CAN bus.
Finally, I redesigned the whole stuff as VioletVynil recommended.
I created panels, add system variables and hooked them to controls on panels, wrote some code in CAPL for calculating checksum and periodic transmit of the message and it runs! Without any problems! And yes additional CRC on the payload is used for additional safety (railway application). I didn't designed communication protocol, I just got it.
things are like this:
I used AsyncSocket to connect with server. when the server send some bytes to client at a time, app will invoke (onSocket: didReadData: withTag:) method; Sometimes, because of the network or other reason, some bytes arrived and the rest bytes arrived later( which means some bytes are delayed).(timeOut = -1)
==================================
Question: how much times did the method(onSocket: didReadData: withTag: ) invoke?
1)only one time - it will wait automatically until the bytes are complete?
2)2 or more times - some arrived(invoke), other arrived(invoke)、、、、、like so?
===================================
which thoughts is right? plz geiv me some advice. Thanks very much.
OK, maybe it's just like this.
Transfer data on TCP: when you send 1000 bytes at a time, because of lag or other reasons, you may receive the 900 bytes first, but the TCP socket will wait the rest 100 bytes
automatically. So if I use asyncSocket to transfer datas and set the timeout, during these seconds, I don't need to deal with the lagged data.
=========================
EDIT
maybe the title of ths question is not appropriate, no one cares the question.
I used the method -readDataToLength: instead, first read header.length of data, and parse it, then read the body.length of data;
I have an RFID scanner attached to a RedPark serial cable connected to an iPad app. When people scan their RFID cards, I get a callback with -readBytesAvailable:. However, sometimes it doesn't give me the entire RFID in one call. Sometimes it send it in two calls.
How can I determine if I've received everything? When my code takes the first callback's data and tries to use it, I get an error, because let's say the RFID was "123456789" sometimes I'll get one call with #"12" and a second call with #"3456789". So I try to process #"12" and get a user not found error, then I try to process #"3456789" and get a user not found error.
How can I tell if I'm done reading data? The lengths of the RFIDs can vary from vendor to vendor, so I can't just assume I need to read a certain number of digits.
This is the method I use to receive the data from the scanner through the RedPark:
- (void) readBytesAvailable:(UInt32)length {
NSLog(#"readBytesAvailable: %lu", length);
UInt8 rxLoopBuff[LOOPBACK_TEST_LEN];
[self.rfidManager read:rxLoopBuff Length:length];
NSString *rfid = [[NSString alloc] initWithBytes:rxLoopBuff length:length encoding:NSUTF8StringEncoding];
NSLog(#"rfid=%#", rfid);
[self receivedScanOfRFID:rfid];
}
Serial port gives you no control over packetization. Data is just a stream of bytes with no way to predict which bytes appear in each read call. You have to parse the data stream itself to interpret the contents and understand start/end of your messages. You either need to look for a reliable terminating character or potentially use a timeout approach where you do multiple reads until you get no more data for some period of time. I don't recommend the timeout approach.
I have a device that sends data to my server via gprs . The problem is that it sends raw data and i don't know where i can stop the reading
Currently i am using something TIdHttpServer and something like this to read the strings :
var
s : string;
repeat
s:=s+acontext.Connection.Socket.ReadChar;
until acontext.Connection.Socket.InputBufferIsEmpty;
Is there a better solution to my problem ?
TCP is stream oriented. If the protocol is unknown, the server only can try to read into a byte array (if memory is not a problem) or a file stream. If the client disconnects normally, the data is 'complete'. Unfortunately, if the protocol is unknown, the server can not tell wether the client died or disconnected normally.
InputBufferIsEmpty does not help, as it only says if there is data in the (TCP) buffer - and depending on latency this can happen frequently, but it does not mean that there are no more in-flight bytes.
You could try to 'reverse engineer' the protocol, by sending known strings over the client devices. But if the sender is a black box, there can be many special cases - think of encoding or 'escape' characters etc.
You could make up you own protocol.
Some ideas are:
use a special character or characters combo to define the end of the
message.
append at the start of the message some fixed size field with the size of the message
I'm facing problem with TCpindy connection.readln method , I had no control in the other side sending data , when using Readln method in server side application hang (because receiving data don't contain carrige return ) , i'm trying readstring method but without success
Is there any suggestion to encouter this problem , me be looking for other component rather than indy ,
I need to get data from other client (tcp connection ) without any information about size of receiving data and without carriage return at the end of each frame.
You have to know how the data is being sent in order to read it properly. TCP is a byte stream, the sender needs to somehow indicate where one message ends and the next begins, either by:
prefixing each message with its
length
putting unique delimiters in between
each message
pausing in time between each message
Indy can handle all of these possibilities, but you need to identify which one is actually being used first.
Worse case scenerio, use the CurrentReadBuffer() method, which returns a String of whatever raw bytes are available at that moment.