2

Is there a way to detect STX (Start of Text) and ETX (End of Text) character sequences in a message received by recv() in c++? I'm trying fix any partial reads that may happen in TCP so that I can reform the complete message.

Thank you!

EDIT1:

Did the following as per the answer by unwind:

char c = '\x02';
if(memchr((*it).c_str(), c, numberOfCharactersRead) != NULL) 
    cout << "STX found" << endl;

Still I didn't manage to detect the character. Any issue with this implementation? 'it' is an iterator for a vector of the type string.

EDIT2:

This is the complete code for receiving data and checking for the character:

int numberOfCharactersRead = 0;

    do {
        char msgBuffer[1000];
        memset(msgBuffer, 0, 1000);
        numberOfCharactersRead = recv(clientSideSocket, msgBuffer, (1000 - 1), 0);
        if (numberOfCharactersRead < 0) {
            close(clientSideSocket);
        }
        else if (numberOfCharactersRead == 0)
            close(clientSideSocket);
        else {
            char c = '\x02';
            if(memchr(msgBuffer, c, numberOfCharactersRead) != NULL) 
                cout << "STX found" << endl;
            memset(msgBuffer, 0, 1000);
        }

    } while (numberOfCharactersRead > 0); 

So, I'm simply checking for the STX, not yet concatenating the buffered data. However, the check for STX is still failing. Kindly let me know any issue in this approach.

Thanks.

EDIT3:

I got the following hex value for a sample message:

3C 31 34 32 3E 4F 63 74 20 32 35 20 31 31 3A 33 39 3A 31 32 20 6C 6F 63 61 6C 68 6F 73 74 20 5B 20 32 30 31 32 2D 4F 63 74 2D 32 35 20 31 31 3A 33 39 3A 31 32 2C 36 31 33 20 5D 20 20 20 20 49 4E 46 4F 20 7B 20 4D 61 69 6E 2E 6A 61 76 61 20 7D 20 2D 20 74 65 73 74 20 69 6E 66 6F 72 6D 61 74 69 6F 6E 20 6D 65 73 73 61 67 65 20

So the hex value for the STX/ETX is not present. That mean can't use STX and ETX for checking the message formation.

Mike Pennington
  • 41,899
  • 19
  • 136
  • 174
Izza
  • 2,389
  • 8
  • 38
  • 60
  • Why are you using strings at all? Data that can contain STX and ETX is surely just as likely to contain null chars, which will break this code. Just look for it in the buffer you called recv() with. *Then* assemble your messages, once you know where they are. – user207421 Oct 24 '12 at 12:21
  • Where is "numberOfCharactersRead" coming from and what is its value? You probably want `(*it).data()` and `(*it).length()`; there's not need to convert it to a NUL-terminate "c" string in this case. Dumping the hex values of your strings may provide some insight. – Brian White Oct 24 '12 at 12:49
  • @BrianWhite: Thanks for the info. numberOfCharactersRead are the number of bytes received from the recv() function. I used (*it).data() as well, didn't work. Any suggestions? – Izza Oct 24 '12 at 12:58
  • @Izza, yes. "Dumping the hex values of your strings may provide some insight." – Brian White Oct 24 '12 at 16:34
  • @Izza If you can't find an STX or ETX in the data, have you considered the possibility that they aren't there? Either because nobody is sending them, or because the STX is in a preceding chunk and the STX is in a subsequent chunk? – user207421 Oct 25 '12 at 02:36
  • @BrianWhite: missed that part of the earlier comment. Just checked it. EJP: yes, it seems this is the case. Thanks for the suggestion. – Izza Oct 25 '12 at 06:25

1 Answers1

8

Well, STX and ETX are not "sequences", they are single characters. So you should be able to use a plain memchr() call to search for the characters.

The character values are simply '\x02' for STX and '\x03' for ETX.

Note that you will need to pass in the received size. Since (I assume) there's no guarantee that a partially received message is 0-terminated, you can't use strchr().

unwind
  • 391,730
  • 64
  • 469
  • 606
  • Thanks for the answer. Edited the original with what I tried. But still could not detect STX. – Izza Oct 24 '12 at 10:56