Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / количество байт в порту c++ linux / 25 сообщений из 26, страница 1 из 2
26.07.2013, 14:58
    #38345327
fs99
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
Доброго времени суток.

Пытаюсь реализовать свой протокол передачи данных по COM порту и столкнулся с вопросом о том, а как же узнать сколько байт в порту уже принято перед чтением этих данных.

Объясняю для чего:
в получаемых пакетах данных (массив байт) в начале каждого пакета идет так называемая шапка длиной в 8 байт, все остальное непосредственно данные пакета.

а так как в шапке содержится информация о том, какова длина последующих данных, то возникает необходимость сначала получить необходимые 8 байт шапки пакета.

Ранее я всегда программировал на delphi и на С++ под linux начал буквально вчера.
можно сказать это всего лишь третий по счету написанный мною класс.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
/////////////////////////////////////////////////////////////////////////////////////////
//
// Calligraff TTL protocol class
// Calligraff.Ru
//
/////////////////////////////////
 
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <stdlib.h>
using namespace std;
 
class CCTTLProt
{
    private:
 
        int TTLHND;
        bool isHDR;
 
        void ReadCycleDo()
        {
            int RcvdDataLen;
            ReadingProcess = True;
            isHDR = false;
            do {
 
                RcvdDataLen = <КАК ЗДЕСЬ ПОЛУЧИТЬ КОЛИЧЕСТВО БАЙТ В ПОРТУ???>;
                if ( isHDR == true )
                {
                    if ( RcvdDataLen >= 8 )
                    {
                        // читаем только первые 8 байт
                    } else {
                        // Какие-то левые
                    }
                } else {
                    // читаем оставшиеся данные
                }
 
            } while( ReadingProcess != false );
        }
 
    public:
 
        bool ReadingProcess = false;
 
        bool Init(string Device)
        {
            TTLHND = open(Device.c_str(), O_RDWR | O_NOCTTY );
            if(! TTLHND ){
                fprintf( stderr, "ERROR: (open) %s\n", strerror( errno ) );
                return false;
            }
            struct termios options;
            tcgetattr(TTLHND, &options);            // Get options
            cfsetispeed(&options, B115200);         // Set input speed
            cfsetospeed(&options, B115200);         // Set output speed
            options.c_cflag &= ~PARENB;             // Do not use the parity bit
            options.c_cflag &= ~CSTOPB;             // Use one stop bit
            options.c_cflag &= ~CSIZE;              // 
            options.c_cflag |= CS8;                 // The number of bits at 1 byte
            options.c_cc[VMIN] = 1;                 // Minimum bytes
            options.c_cc[VTIME] = 10;               // Interval in 1/10 sec
            options.c_lflag = ICANON;               // Enable canonical input
            options.c_oflag = 0;                    // RAW output
            tcflush(TTLHND, TCIOFLUSH);
            tcsetattr(TTLHND, TCSANOW, &options);
 
            return true;
        };
 
        bool ReadCycle()
        {
            // ЗАПУСТИТЬ В ОТДЕЛЬНОМ ПОТОКЕ ПРОЦЕДУРУ
            ReadCycleDo();
            return true;
        }
 
        bool Close()
        {
            close(TTLHND);
            return true;
        };
};
...
Рейтинг: 0 / 0
26.07.2013, 15:09
    #38345354
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
fs99а так как в шапке содержится информация о том, какова длина последующих данных,
то возникает необходимость сначала получить необходимые 8 байт шапки пакета.

Ну так что тебе мешает в цикле восемь раз получить по одному байту, сложить их в буфер и
радоваться жизни?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
26.07.2013, 15:26
    #38345395
fs99
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
Dimitry Sibiryakovfs99а так как в шапке содержится информация о том, какова длина последующих данных,
то возникает необходимость сначала получить необходимые 8 байт шапки пакета.

Ну так что тебе мешает в цикле восемь раз получить по одному байту, сложить их в буфер и
радоваться жизни?


ну ведь там может и не быть 8 байт (а быть например 6 или 5), да и как-то не красиво это делать в цикле.
тем более наличие >= 8 байт в порту указывает на то, что там вообще есть данные и эти данные содержат заголовок
...
Рейтинг: 0 / 0
26.07.2013, 15:33
    #38345415
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
fs99ну ведь там может и не быть 8 байт (а быть например 6 или 5)

Ну так получишь эти 5 или 6 сейчас, а остальные 3 или 2 - позже. СОМ-порт вообще оперирует
чисто байтами, нигде не гарантируется, что послав 8 байт одной пачкой, на другом конце
получишь эти 8 байт тоже одной пачкой.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
26.07.2013, 15:36
    #38345421
fs99
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
Dimitry Sibiryakovfs99ну ведь там может и не быть 8 байт (а быть например 6 или 5)

Ну так получишь эти 5 или 6 сейчас, а остальные 3 или 2 - позже. СОМ-порт вообще оперирует
чисто байтами, нигде не гарантируется, что послав 8 байт одной пачкой, на другом конце
получишь эти 8 байт тоже одной пачкой.


В принципе как вариант, конечно. Можно попробовать, но все же хотелось бы знать о такой команде/функции о которой я спрашивал.
...
Рейтинг: 0 / 0
26.07.2013, 15:40
    #38345427
fs99
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
можно попробовать собирать получаемые байты в массив байт, далее при наличии в массиве не менее 8 байт и isHDR == true оперировать с ними, а остаток массива уже передавать коду исполняемому в случае isHDR == false и работать в нем пока не будут получены все данные длиной указанной в шапке и после снова переходить в режим isHDR == true
...
Рейтинг: 0 / 0
26.07.2013, 15:42
    #38345438
COM:
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
fs99Dimitry Sibiryakovпропущено...

Ну так что тебе мешает в цикле восемь раз получить по одному байту, сложить их в буфер и
радоваться жизни?


ну ведь там может и не быть 8 байт (а быть например 6 или 5), да и как-то не красиво это делать в цикле.
тем более наличие >= 8 байт в порту указывает на то, что там вообще есть данные и эти данные содержат заголовок

У тебя же стоят параметры порта:

Код: plaintext
1.
2.
3.
            options.c_cc[VMIN] = 1;                 // Minimum bytes
            options.c_cc[VTIME] = 10;               // Interval in 1/10 sec
            options.c_lflag = ICANON;               // Enable canonical input
...
Рейтинг: 0 / 0
26.07.2013, 15:45
    #38345447
fs99
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
fs99можно попробовать собирать получаемые байты в массив байт, далее при наличии в массиве не менее 8 байт и isHDR == true оперировать с ними, а остаток массива уже передавать коду исполняемому в случае isHDR == false и работать в нем пока не будут получены все данные длиной указанной в шапке и после снова переходить в режим isHDR == true

правда тогда может возникнуть ситуация, когда несколько байт утеряно и можем просто завиcнуть в этом цикле b не вернуться вовремя в режим isHRD == true

или еще хуже принять недостающие байты из последовательности нового пакета и тогда нарушена будет целостность обоих.

........
...
Рейтинг: 0 / 0
26.07.2013, 15:48
    #38345457
fs99
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
COM:fs99пропущено...


ну ведь там может и не быть 8 байт (а быть например 6 или 5), да и как-то не красиво это делать в цикле.
тем более наличие >= 8 байт в порту указывает на то, что там вообще есть данные и эти данные содержат заголовок

У тебя же стоят параметры порта:

Код: plaintext
1.
2.
3.
            options.c_cc[VMIN] = 1;                 // Minimum bytes
            options.c_cc[VTIME] = 10;               // Interval in 1/10 sec
            options.c_lflag = ICANON;               // Enable canonical input



Кстати. по поводу параметров:
options.c_cc[VMIN] = 1; - это понятно для меня как условие, что можно считать что есть данные тогда и только тогда, когда принято не менее одного байта

остальные два параметра options.c_cc[VTIME] = 10; и options.c_lflag = ICANON; пока для меня не понятны.

можете проконсультировать.
...
Рейтинг: 0 / 0
26.07.2013, 15:56
    #38345484
COM:
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
fs99COM:пропущено...


У тебя же стоят параметры порта:

Код: plaintext
1.
2.
3.
            options.c_cc[VMIN] = 1;                 // Minimum bytes
            options.c_cc[VTIME] = 10;               // Interval in 1/10 sec
            options.c_lflag = ICANON;               // Enable canonical input



Кстати. по поводу параметров:
options.c_cc[VMIN] = 1; - это понятно для меня как условие, что можно считать что есть данные тогда и только тогда, когда принято не менее одного байта

остальные два параметра options.c_cc[VTIME] = 10; и options.c_lflag = ICANON; пока для меня не понятны.

можете проконсультировать.
Могу, но это подробно расписано в мане termios
...
Рейтинг: 0 / 0
26.07.2013, 15:57
    #38345487
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
fs99В принципе как вариант, конечно. Можно попробовать, но все же хотелось бы знать о такой команде/функции о которой я спрашивал.

А о какой ты спрашивал ?
...
Рейтинг: 0 / 0
26.07.2013, 15:59
    #38345491
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
fs99fs99можно попробовать собирать получаемые байты в массив байт, далее при наличии в массиве не менее 8 байт и isHDR == true оперировать с ними, а остаток массива уже передавать коду исполняемому в случае isHDR == false и работать в нем пока не будут получены все данные длиной указанной в шапке и после снова переходить в режим isHDR == true

правда тогда может возникнуть ситуация, когда несколько байт утеряно и можем просто завиcнуть в этом цикле b не вернуться вовремя в режим isHRD == true

или еще хуже принять недостающие байты из последовательности нового пакета и тогда нарушена будет целостность обоих.

........

Я вообще ничего не понял. ЭТо -- последовательный порт. Он читает байты последовательно, как ни пародоксально.
Сначаала один, потом другой, потом третий. На пакеты этот поток делишь уже ты сам.
...
Рейтинг: 0 / 0
26.07.2013, 16:04
    #38345503
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
fs99,

автор RcvdDataLen = <КАК ЗДЕСЬ ПОЛУЧИТЬ КОЛИЧЕСТВО БАЙТ В ПОРТУ???>;

Да никак не получить. Ты просто должен читать оттуда байты и обрабатывать.
Вся работа с терминалами и с портами устоена так, что обработка может быть сделана последовательно.
...
Рейтинг: 0 / 0
26.07.2013, 16:05
    #38345508
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
        void ReadCycleDo()
        {
            int RcvdDataLen;
            ReadingProcess = True;
            isHDR = false;
            do {
 
                RcvdDataLen = <КАК ЗДЕСЬ ПОЛУЧИТЬ КОЛИЧЕСТВО БАЙТ В ПОРТУ???>;
                if ( isHDR == true )
                {
                    if ( RcvdDataLen >= 8 )
                    {
                        // читаем только первые 8 байт
                    } else {
                        // Какие-то левые
                    }
                } else {
                    // читаем оставшиеся данные
                }
 
            } while( ReadingProcess != false );
        }




А где собственно чтение ?
Чтение из порта без чтения -- оригинально...
...
Рейтинг: 0 / 0
26.07.2013, 16:13
    #38345537
sherzod_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
MasterZivЯ вообще ничего не понял. ЭТо -- последовательный порт. Он читает байты последовательно, как ни пародоксально.
Сначаала один, потом другой, потом третий. На пакеты этот поток делишь уже ты сам. То что байты последовательно это да, с любым портом вроде так. Но насколько я помню со времен своих школьных опытов с лампочками на портах, последовательным он называется потому, что данные передаются побитово , в отличии от LPT порта на контакты которого можно выставить 1 байт сразу.
...
Рейтинг: 0 / 0
26.07.2013, 16:25
    #38345572
sherzod_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
fs99fs99можно попробовать собирать получаемые байты в массив байт, далее при наличии в массиве не менее 8 байт и isHDR == true оперировать с ними, а остаток массива уже передавать коду исполняемому в случае isHDR == false и работать в нем пока не будут получены все данные длиной указанной в шапке и после снова переходить в режим isHDR == true
правда тогда может возникнуть ситуация, когда несколько байт утеряно и можем просто завиcнуть в этом цикле b не вернуться вовремя в режим isHRD == true
или еще хуже принять недостающие байты из последовательности нового пакета и тогда нарушена будет целостность обоих.
Для потоковых (не REST) протоколов передачи, используют маркировку конца и начала пакета специальной последовательностью байт, которая в принципе не может встречаться в данных, или если встречается то маскируется. Например, вы можете закодировать данные в base64 и передавать их в кодировке utf8, а в качестве маркера начала и конца пакета использовать 0xFFFE.
...
Рейтинг: 0 / 0
26.07.2013, 16:40
    #38345621
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
sherzod_MasterZivЯ вообще ничего не понял. ЭТо -- последовательный порт. Он читает байты последовательно, как ни пародоксально.
Сначаала один, потом другой, потом третий. На пакеты этот поток делишь уже ты сам. То что байты последовательно это да, с любым портом вроде так. Но насколько я помню со времен своих школьных опытов с лампочками на портах, последовательным он называется потому, что данные передаются побитово , в отличии от LPT порта на контакты которого можно выставить 1 байт сразу.


Именно так. Но уж никак это не блоковое устройство.
...
Рейтинг: 0 / 0
26.07.2013, 16:54
    #38345661
COM:
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
sherzod_fs99пропущено...

правда тогда может возникнуть ситуация, когда несколько байт утеряно и можем просто завиcнуть в этом цикле b не вернуться вовремя в режим isHRD == true
или еще хуже принять недостающие байты из последовательности нового пакета и тогда нарушена будет целостность обоих.
Для потоковых (не REST) протоколов передачи, используют маркировку конца и начала пакета специальной последовательностью байт, которая в принципе не может встречаться в данных, или если встречается то маскируется. Например, вы можете закодировать данные в base64 и передавать их в кодировке utf8, а в качестве маркера начала и конца пакета использовать 0xFFFE.
В контексте вопроса ТС это называется санонический режим. И разделитель "блоков" - перевод строки. И побайтно читать неполучится.
...
Рейтинг: 0 / 0
26.07.2013, 17:24
    #38345721
ДохтаР
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
fs99Dimitry Sibiryakovпропущено...

Ну так получишь эти 5 или 6 сейчас, а остальные 3 или 2 - позже. СОМ-порт вообще оперирует
чисто байтами, нигде не гарантируется, что послав 8 байт одной пачкой, на другом конце
получишь эти 8 байт тоже одной пачкой.


В принципе как вариант, конечно. Можно попробовать, но все же хотелось бы знать о такой команде/функции о которой я спрашивал.

Для сокетов есть параметр getsockopt (не помню давно этим пользовался, уже лет 5 ничего не пишу)
при котором он возвращает количество байт в буфере достопные на чтение блокирующей операцией без ожидания прихода из сети чего либо еще.

возможно для компортов есть что то подобное.
...
Рейтинг: 0 / 0
26.07.2013, 18:39
    #38345898
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
fs99Пытаюсь реализовать свой протокол передачи данных по COM порту PPP чем не угодил???
...
Рейтинг: 0 / 0
28.07.2013, 10:48
    #38346548
ДохтаР
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
Basil A. Sidorovfs99Пытаюсь реализовать свой протокол передачи данных по COM порту PPP чем не угодил???


PPP немного не то .

надо cu смотреть.
Думаю в его исходниках ТС найдет все, что ему нужно.
...
Рейтинг: 0 / 0
29.07.2013, 08:43
    #38346973
fs99
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
хм..

тогда следующая ситуация:

Пришло какое-то количество байт (неизвестное количество), в заголовке моем уже есть, ну скажем 3 из 8 байт.
Значит мне осталось прочитать 5 для заголовка. прийти в порт может конечно и менее пяти, но допустим пришло 9.
Следовательно мне нужно прочитать только 5, а оставшиеся 4 байта оставить в порту для другой функции.

вот как я это делал на Delphi:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
var
   buf : array[0..128] of byte;
   GetDataLen, Bytes, fact : Integer;
   FLAP_Item : TFLAP_Item;
begin
 GetDataLen := Socket.ReceiveLength;
 if LUSRCFG.isHDR then begin  // is it a flap header ?
    if GetDataLen >= 6 then begin
       Socket.ReceiveBuf(LUSRCFG.FLAP,SizeOf(LUSRCFG.FLAP));
       LUSRCFG.NeedBytes := swap(LUSRCFG.FLAP.Len);
       LUSRCFG.Index := 0;   // FLAP_DATA[0]
       LUSRCFG.isHDR := false; // goto FLAP_DATA
    end else begin
       Socket.ReceiveBuf(buf,GetDataLen);
       formMain.M(formDEBUG.Memo1,Dim2Hex(@(buf),GetDataLen));
    end;
 end else begin  // DATA-BLOCK
    Bytes := LUSRCFG.NeedBytes;
    fact := Socket.ReceiveBuf(LUSRCFG.FLAP_DATA[LUSRCFG.Index],Bytes);
    inc(LUSRCFG.Index,fact);
    dec(LUSRCFG.NeedBytes,fact);
    if LUSRCFG.NeedBytes = 0 then begin
       FLAP_Item := TFLAP_Item.Create;
       FLAP_Item.FLAP := LUSRCFG.FLAP;
       FLAP_Item.DATA := LUSRCFG.FLAP_DATA;
       FLAP_Item_List.Add(FLAP_Item);
       LUSRCFG.isHDR := true; // goto FLAP_HDR
    end;
 end;
end;



Очень удобно заранее знать количество байт в порту и далее с этими знаниями уже оперировать байтами.
...
Рейтинг: 0 / 0
29.07.2013, 08:59
    #38346976
sherzod_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
fs99хм..
Очень удобно заранее знать количество байт в порту и далее с этими знаниями уже оперировать байтами. Вы должны понять что именно эта фича которая вам требуется, должна быть реализована вами. С портом вы должны работать как с потоком байт а не как с блочным устройством на котором доступен какой-то блок. То есть у вас должен быть транспортный слой, а все другие функции должны обращаться к нему. Прочитайте все ответы которые вам дали более вдумчиво и внимательно.
...
Рейтинг: 0 / 0
31.07.2013, 09:39
    #38349639
fs99
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
ВОПРОС РЕШЕН!!!

Получение числа доступных байтов

Вызов FIONREAD ioctl получает число байтов в приемном буфере последовательного порта. Также как и в случае с TIOCMGET вам необходимо передать указатель на integer переменную для сохранения результата:

Листинг 7 - Получение числа байтов в приемном буфере.

#include <unistd.h>
#include <termios.h>

int fd;
int bytes;

ioctl(fd, FIONREAD, &bytes);
Это может быть полезно при опросе наличия данных от последовательного порта, когда ваша программа определяет количество байтов в приемном буфере до того как читать данные из последовательного порта.
...
Рейтинг: 0 / 0
31.07.2013, 09:41
    #38349642
fs99
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
количество байт в порту c++ linux
fs99ВОПРОС РЕШЕН!!!

Получение числа доступных байтов

Вызов FIONREAD ioctl получает число байтов в приемном буфере последовательного порта. Также как и в случае с TIOCMGET вам необходимо передать указатель на integer переменную для сохранения результата:

Листинг 7 - Получение числа байтов в приемном буфере.

#include <unistd.h>
#include <termios.h>

int fd;
int bytes;

ioctl(fd, FIONREAD, &bytes);
Это может быть полезно при опросе наличия данных от последовательного порта, когда ваша программа определяет количество байтов в приемном буфере до того как читать данные из последовательного порта.

В дополнение: http://www.opennet.ru/docs/RUS/serial_guide/index.html#5_1_3
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / количество байт в порту c++ linux / 25 сообщений из 26, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]