powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / количество байт в порту c++ linux
26 сообщений из 26, показаны все 2 страниц
количество байт в порту c++ linux
    #38345327
Фотография fs99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброго времени суток.

Пытаюсь реализовать свой протокол передачи данных по 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
количество байт в порту c++ linux
    #38345354
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fs99а так как в шапке содержится информация о том, какова длина последующих данных,
то возникает необходимость сначала получить необходимые 8 байт шапки пакета.

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

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


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

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

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


В принципе как вариант, конечно. Можно попробовать, но все же хотелось бы знать о такой команде/функции о которой я спрашивал.
...
Рейтинг: 0 / 0
количество байт в порту c++ linux
    #38345427
Фотография fs99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
можно попробовать собирать получаемые байты в массив байт, далее при наличии в массиве не менее 8 байт и isHDR == true оперировать с ними, а остаток массива уже передавать коду исполняемому в случае isHDR == false и работать в нем пока не будут получены все данные длиной указанной в шапке и после снова переходить в режим isHDR == true
...
Рейтинг: 0 / 0
количество байт в порту c++ linux
    #38345438
COM:
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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
количество байт в порту c++ linux
    #38345447
Фотография fs99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fs99можно попробовать собирать получаемые байты в массив байт, далее при наличии в массиве не менее 8 байт и isHDR == true оперировать с ними, а остаток массива уже передавать коду исполняемому в случае isHDR == false и работать в нем пока не будут получены все данные длиной указанной в шапке и после снова переходить в режим isHDR == true

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

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

........
...
Рейтинг: 0 / 0
количество байт в порту c++ linux
    #38345457
Фотография fs99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
количество байт в порту c++ linux
    #38345484
COM:
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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
количество байт в порту c++ linux
    #38345487
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fs99В принципе как вариант, конечно. Можно попробовать, но все же хотелось бы знать о такой команде/функции о которой я спрашивал.

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

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

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

........

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

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

Да никак не получить. Ты просто должен читать оттуда байты и обрабатывать.
Вся работа с терминалами и с портами устоена так, что обработка может быть сделана последовательно.
...
Рейтинг: 0 / 0
количество байт в порту c++ linux
    #38345508
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: 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
количество байт в порту c++ linux
    #38345537
sherzod_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivЯ вообще ничего не понял. ЭТо -- последовательный порт. Он читает байты последовательно, как ни пародоксально.
Сначаала один, потом другой, потом третий. На пакеты этот поток делишь уже ты сам. То что байты последовательно это да, с любым портом вроде так. Но насколько я помню со времен своих школьных опытов с лампочками на портах, последовательным он называется потому, что данные передаются побитово , в отличии от LPT порта на контакты которого можно выставить 1 байт сразу.
...
Рейтинг: 0 / 0
количество байт в порту c++ linux
    #38345572
sherzod_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fs99fs99можно попробовать собирать получаемые байты в массив байт, далее при наличии в массиве не менее 8 байт и isHDR == true оперировать с ними, а остаток массива уже передавать коду исполняемому в случае isHDR == false и работать в нем пока не будут получены все данные длиной указанной в шапке и после снова переходить в режим isHDR == true
правда тогда может возникнуть ситуация, когда несколько байт утеряно и можем просто завиcнуть в этом цикле b не вернуться вовремя в режим isHRD == true
или еще хуже принять недостающие байты из последовательности нового пакета и тогда нарушена будет целостность обоих.
Для потоковых (не REST) протоколов передачи, используют маркировку конца и начала пакета специальной последовательностью байт, которая в принципе не может встречаться в данных, или если встречается то маскируется. Например, вы можете закодировать данные в base64 и передавать их в кодировке utf8, а в качестве маркера начала и конца пакета использовать 0xFFFE.
...
Рейтинг: 0 / 0
количество байт в порту c++ linux
    #38345621
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sherzod_MasterZivЯ вообще ничего не понял. ЭТо -- последовательный порт. Он читает байты последовательно, как ни пародоксально.
Сначаала один, потом другой, потом третий. На пакеты этот поток делишь уже ты сам. То что байты последовательно это да, с любым портом вроде так. Но насколько я помню со времен своих школьных опытов с лампочками на портах, последовательным он называется потому, что данные передаются побитово , в отличии от LPT порта на контакты которого можно выставить 1 байт сразу.


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

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

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


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

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

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


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

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

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

Пришло какое-то количество байт (неизвестное количество), в заголовке моем уже есть, ну скажем 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
количество байт в порту c++ linux
    #38346976
sherzod_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fs99хм..
Очень удобно заранее знать количество байт в порту и далее с этими знаниями уже оперировать байтами. Вы должны понять что именно эта фича которая вам требуется, должна быть реализована вами. С портом вы должны работать как с потоком байт а не как с блочным устройством на котором доступен какой-то блок. То есть у вас должен быть транспортный слой, а все другие функции должны обращаться к нему. Прочитайте все ответы которые вам дали более вдумчиво и внимательно.
...
Рейтинг: 0 / 0
количество байт в порту c++ linux
    #38349639
Фотография fs99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВОПРОС РЕШЕН!!!

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

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

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

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

int fd;
int bytes;

ioctl(fd, FIONREAD, &bytes);
Это может быть полезно при опросе наличия данных от последовательного порта, когда ваша программа определяет количество байтов в приемном буфере до того как читать данные из последовательного порта.
...
Рейтинг: 0 / 0
количество байт в порту c++ linux
    #38349642
Фотография fs99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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++ linux
    #38349991
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fs99,

боюсь, что это только наличие уже принятых байт в буфере. Но это не значит, что нельзя прочитать ещё байты.

Ещё раз, общение с портами (да и на самом деле со всеми устройствами) только последовательное, нужно побайтно читать и обрабатывать.

Чем раньше ты это поймёшь, тем быстрее что-то напишешь путное.
...
Рейтинг: 0 / 0
26 сообщений из 26, показаны все 2 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / количество байт в порту c++ linux
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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