How the "OK" message looks like? - tcp

I have a device that sends data to a server.
Data
[ Client ] == > [ Server ]
After the validation on the server I want to return a message:
OK
[ Client ] < == [ Server ]
Is there a standard "OK" message to return? And an "ERROR" message? How does it looks like? (e.g. ":0011", ":110F")

You've got to design an application-level protocol. TCP is a byte stream, so even the definition of "Data" in your client->server piece needs some protocol so that the receiver can know what bytes make up the data (when to stop reading).
A couple of common types of protocols are...
Length-delimited chunks. Every message starts with a 16 or 32-bit length prefix. Then that many bytes follow. The length needs to be in a defined byte order (see htons, ntohs, etc). Everyone who uses this protocol knows to read the length prefix then read that many bytes. Having defined that "chunk" on the network, you might put a header on the contents of the chunk. Maybe a message type (ACK, NAK, Data, etc) followed by some contents.
ASCII newline delimited. Each message is a line of ASCII (or UTF8, etc) text. It ends at a newline. Newline endings for the lines play the same role as the length prefix for the chunks above. You then define what's in each line (like space or comma-delimited ASCII/UTF8/whatever fields). Somewhere in that you'd define what data looks like, ACK, etc.
I'm sure you could come up with other ideas, but that's the basic job: defining your application-level protocol on top of TCP's byte stream.

Related

What byte range 0- means

What "Range: bytes=0-" header means ? Is the entire file ? I tried sending back 0 bytes and is not working, when I send the entire file it works, but I receive this request more than once in a streaming context, it doesn't look right.
Is the entire file ?
Yes, exactly that.
The spec has the grammar:
byte-range-set = 1#( byte-range-spec / suffix-byte-range-spec )
byte-range-spec = first-byte-pos "-" [ last-byte-pos ]
and also notes:
If the last-byte-pos value is
absent, or if the value is greater than or equal to the current
length of the representation data, the byte range is interpreted as
the remainder of the representation
Additionally:
A client can request the last N bytes of the selected representation
using a suffix-byte-range-spec.
suffix-byte-range-spec = "-" suffix-length
So, valid examples from the spec include:
bytes=-500
bytes=9500-
bytes=0-0,-1
I receive this request more than once in a streaming context
The header indicates that this client understands range requests, and would accept a 206 Partial Content response, rather than the entire file, for efficient streaming (What does the HTTP 206 Partial Content status message mean and how do I fully load resources?).

Check if received more or less than one message

I need to make simple chat application using QTcpSocket and QTcpServer. I understand I should put message size in the beginning of the message to check message bounds. But how should I handle the cases when application receives only part of the message or more than one message?
Or there could be the case when application at first receives incomplete message and after that receives another message. In that situation both messages would be combined in one and only part of second message would be recognized.
You are right. Data from single reading could be incomplete. Read this entry.
You can make up your own protocol for correct data transfer.
Let`s imagine that you have to send text message. You could do it in the next way:
First 4 bytes - message size, next bytes - message.
When you receive first piece of data you can analyze it and understand hove many bytes you are waiting for. When you read all data from the first message, beginning of the next message will contain full message size in the firs 4 bytes.
If your messages have a defined data type (or a series of defined types) and you use Qt >=5.7 then you can use transactions.
The typical example is if your message is a QString (imagine a JSON or XML) you can write it using QDataStream as always, then you read it you can use:
QString messageString;
QDataStream stream(socket);
stream.startTransaction();
stream >> messageString;
if(stream.commitTransaction()){
// The message was received in full
}

Correct Way to Manually Parse HTTP Response

I am working in a language that has extremely low-level TCP support (if you must know, it's UnrealScript). The response received after making a POST request includes the entire HTTP header, status code, body, etc. as a string.
So, I need to parse the response to extract the body text manually. The HTTP 1.1 specification says:
Response = Status-Line
*(( general-header
| response-header
| entity-header ) CRLF)
CRLF
[message-body]
Am I correct in assuming that the best way to do this is to split the string along a double CRLF (carriage return/line feed) and return the second part of this split?
Or are there weird HTTP edge cases I should be aware of?
Am I correct in assuming that the best way to do this is to split the string along a double CRLF
Yes - but what appears in the body may be compressed using three different compressions methods even if you told the server you don't accept compressed responses.
Further the body may be split into chunks, in between each chunk is an indicator of the size of the next chunk.
Do you really have no scope for using an off the shelf component for parsing? (I would recommend lib curl).

Sending files through connect direct from UNIX to MAINFRAME

I am sending a file from UNIX to MAINFRAME server via connect direct. I am able to upload the file successfully.At the destination host, when the file is received it is not readable and not in the same format as I sent from the UNIX server.
Below is the transmission job
Direct> Enter a ';' at the end of a command to submit it. Type 'quit;' to exit CLI.
submit maxdelay=unlimited TINIRS process snode=b1ap005
TRANSMIT copy from (file=myFile.txt
pnode
sysopts=":datatype=text"
)
ckpt=1k
to (file=myFile.txt(+1)
snode
DCB=(DSORG=PS,RECFM=VB,LRECL=1500)
disp=(new)
)
pend ;
Please let me know the DCB values needs to be updated. The file I am sending has 3 records of variable length and the maximum length of record is 1500.
Actually, that looks almost right. But if your maximum record length is 1500 characters (exclusive of the NL at the end of the line), your LRECL should be at least 1504. But don't skimp on the maximum - there's no cost or penalty to larger values (up to 32767). And NealB's correct - if this is a text file, you may need to specify a character-set translation - but I don't know how to do that in CONNECT:Direct.
C:D automatically converts ascii to EBCDIC when DATATYPE=TEXT is used. To be positive, you may want to use ":datatype=text:xlate=yes:".

Question about POP3 message termination octet

This is from the POP3 RFC.
"Responses to certain commands are multi-line. In these cases, which
are clearly indicated below, after sending the first line of the
response and a CRLF, any additional lines are sent, each terminated
by a CRLF pair. When all lines of the response have been sent, a
final line is sent, consisting of a termination octet (decimal code
046, ".") and a CRLF pair. If any line of the multi-line response
begins with the termination octet, the line is "byte-stuffed" by
pre-pending the termination octet to that line of the response.
Hence a multi-line response is terminated with the five octets
"CRLF.CRLF". When examining a multi-line response, the client checks
to see if the line begins with the termination octet. If so and if
octets other than CRLF follow, the first octet of the line (the
termination octet) is stripped away. If so and if CRLF immediately
follows the termination character, then the response from the POP
server is ended and the line containing ".CRLF" is not considered
part of the multi-line response."
Well, i have problem with this, for example gmail sometimes sends the termination octet and then in the NEXT LINE sends the CRLF pair. For example:
"+OK blah blah\r\n"
"blah blah.\r\n"
"\r\n"
That's very rare, but it happens sometimes, so obviously i'm unable to determine the end of the message in such case, because i'm expecting a line that consists of '.\r\n'. Seriously, is Gmail violating the POP3 protocol or i'm doing something wrong? Also i have a second question, english is not my first language so i cannot understand that completely:
"If any line of the multi-line response begins with the termination octet, the line is "byte-stuffed" by pre-pending the termination octet to that line of the response.
Hence a multi-line response is terminated with the five octets "CRLF.CRLF"."
When exactly CRLF.CRLF is used? Can someone gives me a simple example? The rfc says that is used when any line of the response begins with the termination octet. But i don't see any lines that starts with '.' in the messages that are terminated with CRLF.CRLF. I checked that. Maybe i don't understand something, that's why i'm asking.
It would help very much if you posted the code you are using to read the socket. But I will attempt to answer the second part of your question with this example:
If the response is:
hello world\r\n
we are doing fine\r\n
.500 is same as one-half\r\n
this is the last line\r\n
the server must send it as:
hello world\r\n
we are doing fine\r\n
..500 is same as one-half\r\n
this is the last line\r\n
.\r\n
So you can see where it 'byte stuffed' an extra '.' so the '.500' can be distinguished as part of the response. Also the final five octets are '\r\n.\r\n'.

Resources