TCP IP очередь запросов...
От: -Cheese-  
Дата: 19.05.05 08:58
Оценка:
Вот назрел такой вопрос пишу сервер, кот. слушает по определённому порту клиента.
Работа в режиме запрос-ответ.
Иногда возникают ситуации, когда приходит запрос и готовится на него ответ, за это время клиент может ещё слать мне запросы.... Так вот после ответа приходят ко мне запросы, а вернее сказать запрос который есть склееные запросы к серверу за время пока отвечал сервер... а это не есть хорошо
Можно ли как-то это пофиксить? Чтоб они приходили в порядке очереди?

P.s.: многопоточность не подходит.
P.s.1: MS VC++ ; MFC; в основе — берклиевский классический сервер.
... << RSDN@Home 1.1.4 beta 5 rev. 395>>

24.05.05 10:46: Перенесено модератором из 'C/C++. Прикладные вопросы' — Odi$$ey
Re: TCP IP очередь запросов...
От: CrystaX Россия https://crystax.me/
Дата: 19.05.05 09:03
Оценка: 1 (1) +1
Здравствуйте, -Cheese-, Вы писали:

C>Вот назрел такой вопрос пишу сервер, кот. слушает по определённому порту клиента.

C>Работа в режиме запрос-ответ.
C>Иногда возникают ситуации, когда приходит запрос и готовится на него ответ, за это время клиент может ещё слать мне запросы.... Так вот после ответа приходят ко мне запросы, а вернее сказать запрос который есть склееные запросы к серверу за время пока отвечал сервер... а это не есть хорошо
C>Можно ли как-то это пофиксить? Чтоб они приходили в порядке очереди?

TCP? Тогда маркер в конце каждого сообщения или размер сообщения в самом начале.
Если UDP, то проблемы нет — приходящие дейтаграммы не склеиваются в одну. Правда, есть риск их потери.

C>P.s.: многопоточность не подходит.

C>P.s.1: MS VC++ ; MFC; в основе — берклиевский классический сервер.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[2]: TCP IP очередь запросов...
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 19.05.05 09:17
Оценка: 1 (1)
Здравствуйте, CrystaX, Вы писали:

CX>Здравствуйте, -Cheese-, Вы писали:


C>>Вот назрел такой вопрос пишу сервер, кот. слушает по определённому порту клиента.

C>>Работа в режиме запрос-ответ.
C>>Иногда возникают ситуации, когда приходит запрос и готовится на него ответ, за это время клиент может ещё слать мне запросы.... Так вот после ответа приходят ко мне запросы, а вернее сказать запрос который есть склееные запросы к серверу за время пока отвечал сервер... а это не есть хорошо

Это вообще фундаментальная особенность TCP-трафика: пакеты, которые на отправляющей стороне отсылаются отдельно, поступать могут на принимающую сторону либо склеенными, либо наоборот -- разделенными на более мелкие части.

C>>Можно ли как-то это пофиксить? Чтоб они приходили в порядке очереди?


CX>TCP? Тогда маркер в конце каждого сообщения или размер сообщения в самом начале.

+1

Именно. Причем нужно будет позаботиться о буфере куда данные из канала поступают и там парсятся. Те данные, которые успешно распарсены из буфера изымаются. Остальны остаются ждать продолжения.

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

Лично я использую размер сообщения в его залоговке.

CX>Если UDP, то проблемы нет — приходящие дейтаграммы не склеиваются в одну. Правда, есть риск их потери.


C>>P.s.: многопоточность не подходит.

C>>P.s.1: MS VC++ ; MFC; в основе — берклиевский классический сервер.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: TCP IP очередь запросов...
От: CrystaX Россия https://crystax.me/
Дата: 19.05.05 09:25
Оценка:
Здравствуйте, eao197, Вы писали:

E>Если сообщения имеют регулярную текстовую структуру (например, XML), то можно обойтись без меток или размера -- сама структура сообщения позволит выделить сообщение целиком. Но это может быть не эффективно на больших сообщениях.


Пример: HTTP. Есть заголовок Content-Length, в котором указывается длина body.

E>Лично я использую размер сообщения в его залоговке.


Да, это самое эффективное, если протокол разрабатываешь сам.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[3]: TCP IP очередь запросов...
От: -Cheese-  
Дата: 19.05.05 10:15
Оценка:
Здравствуйте, eao197, Вы писали:

E>Лично я использую размер сообщения в его залоговке.

ага
мне, например, приходит сообщение в заголовке указано 503 байта
а протокол говорит, что ты мол получил, 1013 байт

т.е. мне нужно следующее начинать с 2+503 байта?
а это все данные там....?
короче возюкаться нужно... а так всё прекрасно начиналось.... (до большой частоты обращений к серверу )
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Re[4]: TCP IP очередь запросов...
От: CrystaX Россия https://crystax.me/
Дата: 19.05.05 10:18
Оценка:
Здравствуйте, -Cheese-, Вы писали:

C>Здравствуйте, eao197, Вы писали:


E>>Лично я использую размер сообщения в его залоговке.

C>ага
C>мне, например, приходит сообщение в заголовке указано 503 байта
C>а протокол говорит, что ты мол получил, 1013 байт

C>т.е. мне нужно следующее начинать с 2+503 байта?

C>а это все данные там....?
C>короче возюкаться нужно... а так всё прекрасно начиналось.... (до большой частоты обращений к серверу )

Если тебе некоторый (как правило, небольшой) процент потерь некритичен, используй UDP.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[5]: TCP IP очередь запросов...
От: -Cheese-  
Дата: 19.05.05 10:31
Оценка:
Здравствуйте, CrystaX, Вы писали:

CX>Если тебе некоторый (как правило, небольшой) процент потерь некритичен, используй UDP.


ещё как критичен.... по шеям можно получить
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Re[6]: TCP IP очередь запросов...
От: CrystaX Россия https://crystax.me/
Дата: 19.05.05 10:45
Оценка:
Здравствуйте, -Cheese-, Вы писали:

C>Здравствуйте, CrystaX, Вы писали:


CX>>Если тебе некоторый (как правило, небольшой) процент потерь некритичен, используй UDP.


C>ещё как критичен.... по шеям можно получить


Ну тогда только с помощью буффера. TCP не гарантирует, что ты получишь весь пакет за один раз или за один раз только один пакет. Даже более того — возможна ситуация, когда при чтении из сокета ты получаешь меньшее количество байт, чем запрашивал, и это ничего не значит. При следующем чтении ты запросто можешь прочитать еще кусок (равный или меньший запрошенному количеству). Конец соединения происходит только при возврате 0 байт.
TCP — потоковый протокол. Разбить его на смысловые фрагменты — уже пользовательская (твоя) задача. Вообще говоря, ничего страшного здесь нет. Сам сейчас занимаюсь подобными вещами.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[4]: TCP IP очередь запросов...
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 19.05.05 10:56
Оценка:
Здравствуйте, CrystaX, Вы писали:

CX>Здравствуйте, eao197, Вы писали:


E>>Если сообщения имеют регулярную текстовую структуру (например, XML), то можно обойтись без меток или размера -- сама структура сообщения позволит выделить сообщение целиком. Но это может быть не эффективно на больших сообщениях.


CX>Пример: HTTP. Есть заголовок Content-Length, в котором указывается длина body.


Я имел в виду чуть-чуть другое. Например, когда сообщения имеют вид:
<message>
    <action>
        <name>Do Something</name>
        <param_count>2</param_count>
        <param ordinal="1" value="With this..." />
        <param ordinal="2" value="...and this!" />
    </action>
</message>


Если поступают большие блоки данных, в которых могут быть множество подобных небольших данных, то их может быть удобно разбирать SAX-парсером. Выбрасывая при этом успешно пропарсенные сообщения и останавливаясь на первом сообщении, которое не поместилось в буфер полностью.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[4]: TCP IP очередь запросов...
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 19.05.05 10:57
Оценка:
Здравствуйте, -Cheese-, Вы писали:

C>Здравствуйте, eao197, Вы писали:


E>>Лично я использую размер сообщения в его залоговке.

C>ага
C>мне, например, приходит сообщение в заголовке указано 503 байта
C>а протокол говорит, что ты мол получил, 1013 байт

C>т.е. мне нужно следующее начинать с 2+503 байта?

C>а это все данные там....?
C>короче возюкаться нужно... а так всё прекрасно начиналось.... (до большой частоты обращений к серверу )

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

Вот, например, как у меня идет разбор входящего трафика:
so_4::ret_code_t
client_connection_t::read()
{
    // Пытаемся прочитать очередную порцию данных.
    unsigned int bytes_to_read = query_read_buf_size();
    auto_ptr_3::vect_ptr_t< char > buf(
        new char[ bytes_to_read ], bytes_to_read );
    unsigned int bytes_read;

    so_4::ret_code_t rc;
    /* m_phys_channel_ptr -- это объект, который физически работает с сокетом. */
    rc = m_phys_channel_ptr->read(
        buf.query(), bytes_to_read, bytes_read );
    if( rc == success )
    {
        // Чтение прошло без ошибок.
        size_t size;
        /* В моем случае данные могут быть заархивированны, метод transform_incoming распаковывает их и помещает в атрибут m_ibuf. */
        rc = transform_incoming( buf.query(), bytes_read, size );

        // Если что-то трансформировали, то нужно
        // поместить это в промежуточный буфер и
        // попробовать разобрать.
        if( rc == success && size )
            /* parse_ibuf -- это виртуальный метод, который переопределяется для разных типов соединений. */
            rc = parse_ibuf();
    }

    return rc;
}

/* Вот в этом производном классе разбираются данные, в которых есть специальный заголовок с длиной сообщения. */
so_4::ret_code_t
sop_client_connection_t::parse_ibuf()
{
    /* Идем в начало буфера чтобы начать его новый просмотр. */
    m_ibuf.set_pos( 0 );
    while( so_4::sop::package_header_t::e_image_size <= m_ibuf.size() )
    {
        // Считываем заголовок пакета и проверяем его.
        so_4::sop::package_header_t header;
        m_ibuf >> header;
        if( header.is_valid() )
        {
            // Заголовок корректен. Обрабатываем тело пакета.
            unsigned int body_size = header.size();
            // Если все тело пакета находится в буфере, то
            // изымаем его и отсылаем на обработку.
            if( so_4::sop::package_header_t::e_image_size +
                body_size <= m_ibuf.size() )
            {
                /* Сюда попадаем только, если в буфере сообщение находится целиком. */
                so_4::rt::msg_auto_ptr_t< msg_sop_package >
                    msg( new msg_sop_package() );
                msg->m_channel = m_comm_channel;
                msg->m_package.insert( 0, m_ibuf,
                    m_ibuf.pos(), body_size );
                // Заблокирован ли канал?
                bool is_blocked = ( msg->m_is_blocked =
                    in_package_processed( body_size ) );
                msg.send( communicator_agent_name(),
                    "msg_sop_package" );

                // Обработанные данные из буфера нужно изъять.
                /* Вот так данные из промежуточного буфера удаляются. После этого указатель перемещается в начало буфера. */
                m_ibuf.erase( 0,
                    so_4::sop::package_header_t::e_image_size +
                    body_size );

                // Если канал оказался заблокированным, то разбор
                // буфера нужно прекратить.
                if( is_blocked )
                    break;
            }
            else
                // В буфере недостаточно данных.
                // Просмотр буфера можно прекратить.
                break;
        }
        else
        {
            // Обнаружен некорректный заголовок.
            return so_4_make_rc( invalid_package_header,
                "Invalid SOP package header" );
        }
    }

    // Если после просмотра в буфере оказалось слишком
    // много данных, то это ошибка.
    if( m_ibuf.size() > m_ibuf_max_size )
    {
        return so_4_make_rc( ibuf_too_large,
            "Input buffer is too large" );
    }

    return so_4::ret_code_t();
}


Так что, если нет желания с такими низкоуровневыми особенностями разбираться, то возьми какую-нибудь готовую библиотеку. Тот же ACE, например. В нем и чтение/запись реализованы. И специальный класс MessageBlock. И специальный класс для перекодировок значений в BigEndian/LittleEndian.

Либо вообще откажись от собственного низкоуровневого протокола в пользу чего-нибудь готового. Например, CORBA, Ice, SOAP, XML-RPC. Или даже собственный протокол поверх HTTP: во-первых, ты получишь готовый транспортный уровень, во-вторых, request/response протоколы на основе HTTP (да и CORBA) могут хорошо маштабироваться (с балансировкой нагрузки на несколько web-серверов) + отказоустойчивость в этом случае есть.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: TCP IP очередь запросов...
От: c0unt Украина  
Дата: 19.05.05 11:06
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, CrystaX, Вы писали:


CX>>Здравствуйте, -Cheese-, Вы писали:


C>>>Вот назрел такой вопрос пишу сервер, кот. слушает по определённому порту клиента.

C>>>Работа в режиме запрос-ответ.
C>>>Иногда возникают ситуации, когда приходит запрос и готовится на него ответ, за это время клиент может ещё слать мне запросы.... Так вот после ответа приходят ко мне запросы, а вернее сказать запрос который есть склееные запросы к серверу за время пока отвечал сервер... а это не есть хорошо

E>Это вообще фундаментальная особенность TCP-трафика: пакеты, которые на отправляющей стороне отсылаются отдельно, поступать могут на принимающую сторону либо склеенными, либо наоборот -- разделенными на более мелкие части.


C>>>Можно ли как-то это пофиксить? Чтоб они приходили в порядке очереди?


CX>>TCP? Тогда маркер в конце каждого сообщения или размер сообщения в самом начале.

E>+1

E>Именно. Причем нужно будет позаботиться о буфере куда данные из канала поступают и там парсятся. Те данные, которые успешно распарсены из буфера изымаются. Остальны остаются ждать продолжения.


E>Если сообщения имеют регулярную текстовую структуру (например, XML), то можно обойтись без меток или размера -- сама структура сообщения позволит выделить сообщение целиком. Но это может быть не эффективно на больших сообщениях.


E>Лично я использую размер сообщения в его залоговке.


Но не только, если протокол свой, и обработка ошибок висит на тебе, можно и даже желательно сделать свой подзаголовок вида 000001002003, в этом случае можно контролировать не только общую длину пакета, независимо от количества сегментов, склеиваеться или нет, но и номер субпакета который пришел и его отдельную длину, имхо в этом случае порядок точно не перепутаеться и в контрольную сумму будет легче поверить
-=Life is full of little surprises=-
Re[5]: TCP IP очередь запросов...
От: CrystaX Россия https://crystax.me/
Дата: 19.05.05 11:09
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, CrystaX, Вы писали:


CX>>Здравствуйте, eao197, Вы писали:


E>>>Если сообщения имеют регулярную текстовую структуру (например, XML), то можно обойтись без меток или размера -- сама структура сообщения позволит выделить сообщение целиком. Но это может быть не эффективно на больших сообщениях.


CX>>Пример: HTTP. Есть заголовок Content-Length, в котором указывается длина body.


E>Я имел в виду чуть-чуть другое. Например, когда сообщения имеют вид:

E>
E><message>
E>    <action>
E>        <name>Do Something</name>
E>        <param_count>2</param_count>
E>        <param ordinal="1" value="With this..." />
E>        <param ordinal="2" value="...and this!" />
E>    </action>
E></message>
E>


E>Если поступают большие блоки данных, в которых могут быть множество подобных небольших данных, то их может быть удобно разбирать SAX-парсером. Выбрасывая при этом успешно пропарсенные сообщения и останавливаясь на первом сообщении, которое не поместилось в буфер полностью.


Да, я понял. Но в данном случае это непринципиально. Ровно так же на этом месте может быть множество HTTP сообщений.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[4]: TCP IP очередь запросов...
От: CrystaX Россия https://crystax.me/
Дата: 19.05.05 11:11
Оценка: +1
Здравствуйте, c0unt, Вы писали:

E>>Лично я использую размер сообщения в его залоговке.


C>Но не только, если протокол свой, и обработка ошибок висит на тебе, можно и даже желательно сделать свой подзаголовок вида 000001002003, в этом случае можно контролировать не только общую длину пакета, независимо от количества сегментов, склеиваеться или нет, но и номер субпакета который пришел и его отдельную длину, имхо в этом случае порядок точно не перепутаеться и в контрольную сумму будет легче поверить


Это неактуально в случае TCP.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[5]: TCP IP очередь запросов...
От: -Cheese-  
Дата: 19.05.05 11:42
Оценка:
Здравствуйте, eao197, Вы писали:

E>Либо вообще откажись от собственного низкоуровневого протокола в пользу чего-нибудь готового. Например, CORBA, Ice, SOAP, XML-RPC. Или даже собственный протокол поверх HTTP: во-первых, ты получишь готовый транспортный уровень, во-вторых, request/response протоколы на основе HTTP (да и CORBA) могут хорошо маштабироваться (с балансировкой нагрузки на несколько web-серверов) + отказоустойчивость в этом случае есть.


не получится... клиент как бы написан не мною и это есть приложение, кот. общается со многими серверами, в том числе и моим по определённому протоколу.
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Re[6]: TCP IP очередь запросов...
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 19.05.05 11:51
Оценка: 2 (1)
Здравствуйте, -Cheese-, Вы писали:

C>Здравствуйте, eao197, Вы писали:


E>>Либо вообще откажись от собственного низкоуровневого протокола в пользу чего-нибудь готового. Например, CORBA, Ice, SOAP, XML-RPC. Или даже собственный протокол поверх HTTP: во-первых, ты получишь готовый транспортный уровень, во-вторых, request/response протоколы на основе HTTP (да и CORBA) могут хорошо маштабироваться (с балансировкой нагрузки на несколько web-серверов) + отказоустойчивость в этом случае есть.


C>не получится... клиент как бы написан не мною и это есть приложение, кот. общается со многими серверами, в том числе и моим по определённому протоколу.


Тогда могу посоветовать посмотреть-таки в сторону ACE и почитать книгу: C++ Network Programming vol1: Mastering Complexity with ACE and Patterns (она была в eMule). Даже если ты ACE и не будешь использовать, то хотя бы для общего развития она будет полезна.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[7]: TCP IP очередь запросов...
От: -Cheese-  
Дата: 20.05.05 08:15
Оценка:
Здравствуйте, CrystaX, Вы писали:

CX>Ну тогда только с помощью буффера. TCP не гарантирует, что ты получишь весь пакет за один раз или за один раз только один пакет. Даже более того — возможна ситуация, когда при чтении из сокета ты получаешь меньшее количество байт, чем запрашивал, и это ничего не значит. При следующем чтении ты запросто можешь прочитать еще кусок (равный или меньший запрошенному количеству). Конец соединения происходит только при возврате 0 байт.

CX>TCP — потоковый протокол. Разбить его на смысловые фрагменты — уже пользовательская (твоя) задача. Вообще говоря, ничего страшного здесь нет. Сам сейчас занимаюсь подобными вещами.

если не сложно.. можно ссылочку (ну или вкратце обьяснить) на то, как склеиваются сообщения (по какому принципу) . Что я их правильно распарсил.

Спасибо!
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Re[8]: TCP IP очередь запросов...
От: CrystaX Россия https://crystax.me/
Дата: 20.05.05 08:27
Оценка:
Здравствуйте, -Cheese-, Вы писали:

C>если не сложно.. можно ссылочку (ну или вкратце обьяснить) на то, как склеиваются сообщения (по какому принципу) . Что я их правильно распарсил.


А принципа никакого нет. Как придут, так и будут склеены.

Вот у меня сейчас сделано так:
Есть буфер необработанных сообщений. Это просто plain text. Я натравливаю на этот буфер парсер. Парсер возвращает три состояния.
1. ОК, сообщение прочитано. В этом случае оно удаляется из буффера (его длина известна, т.к. оно уже распарсено) и производится попытка парсинга следующего сообщения.
2. В буфере лежит корректное сообщение, но не полное (буфер закончился). В таком случае парсинг откладывается на потом, когда придут дополнительные данные. С буфером никаких действий не предпринимается.
3. Парсер выдает ошибку (некорректное сообщение). Обрабатываем ошибочную ситуацию.

В отдельном потоке при этом крутится цикл приема сообщений и помещения их в буфер.

Это одна из возможных схем реализации. Какую именно выбрать тебе — нужно решать на основании твоей задачи.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[9]: TCP IP очередь запросов...
От: -Cheese-  
Дата: 20.05.05 09:06
Оценка:
Здравствуйте, CrystaX, Вы писали:

CX>А принципа никакого нет. Как придут, так и будут склеены.


CX>Вот у меня сейчас сделано так:

CX>Есть буфер необработанных сообщений. Это просто plain text. Я натравливаю на этот буфер парсер. Парсер возвращает три состояния.
CX>1. ОК, сообщение прочитано. В этом случае оно удаляется из буффера (его длина известна, т.к. оно уже распарсено) и производится попытка парсинга следующего сообщения.
CX>2. В буфере лежит корректное сообщение, но не полное (буфер закончился). В таком случае парсинг откладывается на потом, когда придут дополнительные данные. С буфером никаких действий не предпринимается.
CX>3. Парсер выдает ошибку (некорректное сообщение). Обрабатываем ошибочную ситуацию.

CX>В отдельном потоке при этом крутится цикл приема сообщений и помещения их в буфер.


CX>Это одна из возможных схем реализации. Какую именно выбрать тебе — нужно решать на основании твоей задачи.


не совсем понял...
В основном мне приходят склееные >=2 сообщения..
вот к примеру ко мне приходят сообщения вида
(2 байта для размера сообщения) + іmessage1іmessage2
так вот что это за символ (і)? Всегда ли он отделяет сообщение одно от другого?
как мне их отделить?
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Re[10]: TCP IP очередь запросов...
От: CrystaX Россия https://crystax.me/
Дата: 20.05.05 09:11
Оценка:
Здравствуйте, -Cheese-, Вы писали:

C>не совсем понял...

C>В основном мне приходят склееные >=2 сообщения..
C>вот к примеру ко мне приходят сообщения вида
C>(2 байта для размера сообщения) + іmessage1іmessage2
C>так вот что это за символ (і)? Всегда ли он отделяет сообщение одно от другого?
C>как мне их отделить?

Это какие-то части сообщений тоже. TCP не добавляет никаких маркеров. Это поток в чистом виде и ничего более. Ты уверен, что там именно 2, а не 4 байта, обозначающих размер? Кроме того, какое представление целочисленных величин используется (какой byte-order)?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[11]: TCP IP очередь запросов...
От: -Cheese-  
Дата: 20.05.05 09:19
Оценка:
Здравствуйте, CrystaX, Вы писали:

CX>Это какие-то части сообщений тоже. TCP не добавляет никаких маркеров. Это поток в чистом виде и ничего более. Ты уверен, что там именно 2, а не 4 байта, обозначающих размер?

когда не слеиваются, то точно 2 байта

CX>Кроме того, какое представление целочисленных величин используется (какой byte-order)?

Чего?
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Re[12]: TCP IP очередь запросов...
От: CrystaX Россия https://crystax.me/
Дата: 20.05.05 09:21
Оценка:
Здравствуйте, -Cheese-, Вы писали:

C>Здравствуйте, CrystaX, Вы писали:


CX>>Это какие-то части сообщений тоже. TCP не добавляет никаких маркеров. Это поток в чистом виде и ничего более. Ты уверен, что там именно 2, а не 4 байта, обозначающих размер?

C>когда не слеиваются, то точно 2 байта

CX>>Кроме того, какое представление целочисленных величин используется (какой byte-order)?

C>Чего?

О htons, ntohs что-нибудь слышал?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[13]: TCP IP очередь запросов...
От: -Cheese-  
Дата: 20.05.05 10:59
Оценка:
Здравствуйте, CrystaX, Вы писали:

CX>О htons, ntohs что-нибудь слышал?

нет
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Re[14]: TCP IP очередь запросов...
От: CrystaX Россия https://crystax.me/
Дата: 20.05.05 11:08
Оценка:
Здравствуйте, -Cheese-, Вы писали:

C>Здравствуйте, CrystaX, Вы писали:


CX>>О htons, ntohs что-нибудь слышал?

C>нет

Поищи тогда здесь или в MSDN-е. Ключевые слова: network byte order, host byte order.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[15]: TCP IP очередь запросов...
От: -Cheese-  
Дата: 20.05.05 11:33
Оценка:
Здравствуйте, CrystaX, Вы писали:

CX>Поищи тогда здесь или в MSDN-е. Ключевые слова: network byte order, host byte order.

прочитал. вроде понял.
не понял к чему это...

может я не правильно изьяснился в начале.
проблема в следующем:
пакет, который мне приходит имеет след. структуру —
2 байта (число N) + N байт
где N — длина сообщения

т.е. пакеты вида
x1mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
x2mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
x3mmmmmmmmmmmmm

но при большом потоке запросов мне приходит сообщение вида
x1mmmmmmmmmmmmmmmmmmmmmmx2mmmmmmmmmmmmmmmmmmmmx3mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm

где
x1 — длина всего сообщения
x2 — длина второго сообщения
x3 — длина третьего сообщения

Внимание, вопрос:
как мне узнать где начинается x2,x3?
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Re[16]: TCP IP очередь запросов...
От: CrystaX Россия https://crystax.me/
Дата: 20.05.05 11:40
Оценка: +1
Здравствуйте, -Cheese-, Вы писали:

C>Здравствуйте, CrystaX, Вы писали:


CX>>Поищи тогда здесь или в MSDN-е. Ключевые слова: network byte order, host byte order.

C>прочитал. вроде понял.
C>не понял к чему это...

C>может я не правильно изьяснился в начале.

C>проблема в следующем:
C>пакет, который мне приходит имеет след. структуру —
C>2 байта (число N) + N байт
C>где N — длина сообщения

C>т.е. пакеты вида

C>x1mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
C>x2mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
C>x3mmmmmmmmmmmmm

C>но при большом потоке запросов мне приходит сообщение вида

C>x1mmmmmmmmmmmmmmmmmmmmmmx2mmmmmmmmmmmmmmmmmmmmx3mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm

C>где

C>x1 — длина всего сообщения
C>x2 — длина второго сообщения
C>x3 — длина третьего сообщения

C>Внимание, вопрос:

C> как мне узнать где начинается x2,x3?

Ничего не понимаю. Ну прочитал ты первые два байта (x1). Теперь ты знаешь длину первого сообщения. Считываешь x1 байт. Следующие два байта — это уже число x2. Считываешь x2 байт. И т.д.

Я, может, чего-то не понимаю?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[17]: TCP IP очередь запросов...
От: -Cheese-  
Дата: 20.05.05 11:55
Оценка:
Здравствуйте, CrystaX, Вы писали:

CX>Ничего не понимаю. Ну прочитал ты первые два байта (x1). Теперь ты знаешь длину первого сообщения.

CX>Считываешь x1 байт. Следующие два байта — это уже число x2. Считываешь x2 байт. И т.д.
в том то и дело, что х1 — не длина первого сообщения, а длина всего склеенного сообщения!

CX>Я, может, чего-то не понимаю?
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Re[18]: TCP IP очередь запросов...
От: CrystaX Россия https://crystax.me/
Дата: 20.05.05 12:03
Оценка:
Здравствуйте, -Cheese-, Вы писали:

C>Здравствуйте, CrystaX, Вы писали:


CX>>Ничего не понимаю. Ну прочитал ты первые два байта (x1). Теперь ты знаешь длину первого сообщения.

CX>>Считываешь x1 байт. Следующие два байта — это уже число x2. Считываешь x2 байт. И т.д.
C>в том то и дело, что х1 — не длина первого сообщения, а длина всего склеенного сообщения!

То есть это особенность протокола такая? Если да, то никак тебе помочь не могу, не зная протокола. Скажи хоть тогда, что за протокол, а то иначе гадание на кофейной гуще получается
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[19]: TCP IP очередь запросов...
От: -Cheese-  
Дата: 20.05.05 12:10
Оценка:
Здравствуйте, CrystaX, Вы писали:

CX>То есть это особенность протокола такая? Если да, то никак тебе помочь не могу, не зная протокола. Скажи хоть тогда, что за протокол, а то иначе гадание на кофейной гуще получается


TCP\IP
самый обнаковенный... просто вот такая фигня получается со склейкой...
может это глюк?
часто повторяющийся...
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Re[20]: TCP IP очередь запросов...
От: CrystaX Россия https://crystax.me/
Дата: 20.05.05 12:13
Оценка:
Здравствуйте, -Cheese-, Вы писали:

C>Здравствуйте, CrystaX, Вы писали:


CX>>То есть это особенность протокола такая? Если да, то никак тебе помочь не могу, не зная протокола. Скажи хоть тогда, что за протокол, а то иначе гадание на кофейной гуще получается


C>TCP\IP

C>самый обнаковенный... просто вот такая фигня получается со склейкой...

Ты не понял. Я имел в виду высокоуровневый протокол. TCP — это транспортный протокол.

C>может это глюк?

C>часто повторяющийся...

Очень вряд ли. Скорее всего у тебя баг.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[21]: TCP IP очередь запросов...
От: -Cheese-  
Дата: 20.05.05 12:18
Оценка:
Здравствуйте, CrystaX, Вы писали:

CX>

C>>TCP\IP
C>>самый обнаковенный... просто вот такая фигня получается со склейкой...
CX>Ты не понял. Я имел в виду высокоуровневый протокол. TCP — это транспортный протокол.
ну я ещё не волшебник.... только учусь
C>>может это глюк?
C>>часто повторяющийся...

CX>Очень вряд ли. Скорее всего у тебя баг.

ну будем смотреть.

всё равно спасибо за потраченное время!
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Re[22]: TCP IP очередь запросов...
От: CrystaX Россия https://crystax.me/
Дата: 20.05.05 12:22
Оценка:
Здравствуйте, -Cheese-, Вы писали:

C>Здравствуйте, CrystaX, Вы писали:


CX>>

C>>>TCP\IP
C>>>самый обнаковенный... просто вот такая фигня получается со склейкой...
CX>>Ты не понял. Я имел в виду высокоуровневый протокол. TCP — это транспортный протокол.
C>ну я ещё не волшебник.... только учусь
C>>>может это глюк?
C>>>часто повторяющийся...

CX>>Очень вряд ли. Скорее всего у тебя баг.

C>ну будем смотреть.

C>всё равно спасибо за потраченное время!


Приведи минимальный код, на котором проявляется ошибка. Думается, баг будет быстро найден.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[23]: TCP IP очередь запросов...
От: -Cheese-  
Дата: 20.05.05 12:37
Оценка:
Здравствуйте, CrystaX, Вы писали:

CX>Приведи минимальный код, на котором проявляется ошибка. Думается, баг будет быстро найден.

я бы не назвал это ошибкой... просто мне приходит сообщение описанного выше вида...

в основе как я говорил берклиевский классический сервер.
(взял где-то в инете и чуть модифицировал)


bool process_data(SOCKET sock)
{
    /////////////////
        if ((received = recv(sock, buf, RECVBUFSIZ, 0)) != SOCKET_ERROR && received>2) {
      // здесь вот buf может являться тем злополучным сообщением (а может и не быть им).
      buf[received] = '\0';
            pushToStack(buf,received); // тут просто парсером прогоняю сообщение и кладу в стек сообщений
            return true;
    }
    return false;
}

/////////////////////////////////////////////////////////////////////////////
UINT ListenSockets(LPVOID lpvoid)
{
    while (true) {
            ///////////
        if ((accepted = accept(ssocket, (struct sockaddr *) &ca, (socklen_t *)&cal)) != SOCKET_ERROR){
                    int size=sizeof(sockaddr);
                    sockaddr_in adr;
                    int ret=getpeername(accepted,(sockaddr*)&adr,&size);
                    if(adr.sin_addr.S_un.S_addr==IP_CLIENT){
                if(clients.size()==0){
                    sprintf(buffer,"Client connected [%s]",inet_ntoa(adr.sin_addr));
                    clients.push_back(accepted);
                }else{
                    sprintf(buffer,"Client already connected [%s]. Ignored",inet_ntoa(adr.sin_addr));
                    shutdown_socket(&accepted);
                }
            }else{
                sprintf(buffer,"Illegal client want to connect [%s]",inet_ntoa(adr.sin_addr));
                shutdown_socket(&accepted);
            }
            toLog(buffer);
        }
        
        // Preparing descriptor sets
        FD_ZERO(&readfds);
        FD_ZERO(&exfds);
        FD_SET(ssocket, &exfds);
        tv.tv_sec = 1;
        tv.tv_usec = 0;
        maxfd = ssocket;

        for (CL::iterator ii = clients.begin(); ii != clients.end(); ++ii) {
            FD_SET((SOCKET )*ii, &readfds);
            FD_SET((SOCKET )*ii, &exfds);
            maxfd = max(maxfd, (SOCKET )*ii);
        }
    
        // select failing breaks the work
        if (select(maxfd + 1, &readfds, NULL, &exfds, &tv) == -1) break;
        
         // On exception in server socket also breaks immediately
        if(FD_ISSET(ssocket, &exfds)) break;
    
        // Test events on client sockets
        for (ii = clients.begin(); ii != clients.end(); ++ii) {
            if (FD_ISSET(*ii, &exfds)) {
                                toLog("Client exception");
                if (*ii != INVALID_SOCKET) shutdown_socket(&(*ii));
                if ((ii = clients.erase(ii)) == clients.end()) break;
            }
            if (FD_ISSET(*ii, &readfds) && !process_data(*ii)) {
                                toLog("Failed to read client");
                if (*ii != INVALID_SOCKET) shutdown_socket(&(*ii));
                if ((ii = clients.erase(ii)) == clients.end()) break;
            }
        }
    }
    for (CL::iterator ii = clients.begin(); ii != clients.end(); ++ii) {
        if (*ii != INVALID_SOCKET) shutdown_socket(&(*ii));
        if ((ii = clients.erase(ii)) == clients.end()) break;
    }
    /////////////////
  shutdown_socket(&ssocket);
    /////////////////
}



отдельный процесс время от времени читает стек и отвечает на запросы.
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Re[24]: TCP IP очередь запросов...
От: CrystaX Россия https://crystax.me/
Дата: 20.05.05 12:53
Оценка:
Здравствуйте, -Cheese-, Вы писали:

C>Здравствуйте, CrystaX, Вы писали:


CX>>Приведи минимальный код, на котором проявляется ошибка. Думается, баг будет быстро найден.

C>я бы не назвал это ошибкой... просто мне приходит сообщение описанного выше вида...

C>в основе как я говорил берклиевский классический сервер.

C>(взял где-то в инете и чуть модифицировал)

C>
C>bool process_data(SOCKET sock)
C>{
C>    /////////////////
C>        if ((received = recv(sock, buf, RECVBUFSIZ, 0)) != SOCKET_ERROR && received>2) {
C>      // здесь вот buf может являться тем злополучным сообщением (а может и не быть им).
C>      buf[received] = '\0';
C>            pushToStack(buf,received); // тут просто парсером прогоняю сообщение и кладу в стек сообщений
C>            return true;
C>    }
C>    return false;
C>}
C>


Вот здесь неверно. Тебе никто не гарантирует, что данные будут приходить кусками, не меньшими чем 2 или еще сколько байт. Теоретически возможна ситуация, когда данные вообще могут приходить по одному байту за одно чтение. В этом случае ты их потеряешь.

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

C>
C>/////////////////////////////////////////////////////////////////////////////
C>UINT ListenSockets(LPVOID lpvoid)
C>{
C>    while (true) {
C>            ///////////
C>        if ((accepted = accept(ssocket, (struct sockaddr *) &ca, (socklen_t *)&cal)) != SOCKET_ERROR){
C>                    int size=sizeof(sockaddr);
C>                    sockaddr_in adr;
C>                    int ret=getpeername(accepted,(sockaddr*)&adr,&size);
C>                    if(adr.sin_addr.S_un.S_addr==IP_CLIENT){
C>                if(clients.size()==0){
C>                    sprintf(buffer,"Client connected [%s]",inet_ntoa(adr.sin_addr));
C>                    clients.push_back(accepted);
C>                }else{
C>                    sprintf(buffer,"Client already connected [%s]. Ignored",inet_ntoa(adr.sin_addr));
C>                    shutdown_socket(&accepted);
C>                }
C>            }else{
C>                sprintf(buffer,"Illegal client want to connect [%s]",inet_ntoa(adr.sin_addr));
C>                shutdown_socket(&accepted);
C>            }
C>            toLog(buffer);
C>        }
        
C>        // Preparing descriptor sets
C>        FD_ZERO(&readfds);
C>        FD_ZERO(&exfds);
C>        FD_SET(ssocket, &exfds);
C>        tv.tv_sec = 1;
C>        tv.tv_usec = 0;
C>        maxfd = ssocket;

C>        for (CL::iterator ii = clients.begin(); ii != clients.end(); ++ii) {
C>            FD_SET((SOCKET )*ii, &readfds);
C>            FD_SET((SOCKET )*ii, &exfds);
C>            maxfd = max(maxfd, (SOCKET )*ii);
C>        }
    
C>        // select failing breaks the work
C>        if (select(maxfd + 1, &readfds, NULL, &exfds, &tv) == -1) break;
        
C>         // On exception in server socket also breaks immediately
C>        if(FD_ISSET(ssocket, &exfds)) break;
    
C>        // Test events on client sockets
C>        for (ii = clients.begin(); ii != clients.end(); ++ii) {
C>            if (FD_ISSET(*ii, &exfds)) {
C>                                toLog("Client exception");
C>                if (*ii != INVALID_SOCKET) shutdown_socket(&(*ii));
C>                if ((ii = clients.erase(ii)) == clients.end()) break;
C>            }
C>            if (FD_ISSET(*ii, &readfds) && !process_data(*ii)) {
C>                                toLog("Failed to read client");
C>                if (*ii != INVALID_SOCKET) shutdown_socket(&(*ii));
C>                if ((ii = clients.erase(ii)) == clients.end()) break;
C>            }
C>        }
C>    }
C>    for (CL::iterator ii = clients.begin(); ii != clients.end(); ++ii) {
C>        if (*ii != INVALID_SOCKET) shutdown_socket(&(*ii));
C>        if ((ii = clients.erase(ii)) == clients.end()) break;
C>    }
C>    /////////////////
C>  shutdown_socket(&ssocket);
C>    /////////////////
C>}
C>



C>отдельный процесс время от времени читает стек и отвечает на запросы.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[25]: TCP IP очередь запросов...
От: -Cheese-  
Дата: 20.05.05 13:00
Оценка:
Здравствуйте, CrystaX, Вы писали:

CX>Вот здесь неверно. Тебе никто не гарантирует, что данные будут приходить кусками, не меньшими чем 2 или еще сколько байт. Теоретически возможна ситуация, когда данные вообще могут приходить по одному байту за одно чтение. В этом случае ты их потеряешь.


я думаю такого не случится.
сервера стоят рядом на одном хабе.

CX>Не факт, конечно, что это и единственный баг, но это точно надо исправить. Насчет же следующей функции (ListenSockets) — извини, не понял, что она должна делать. Никаких данных ты в ней не читаешь, так откуда же они берутся?

как не читаю...

            if (FD_ISSET(*ii, &readfds) && !process_data(*ii)) {
                                toLog("Failed to read client");
                if (*ii != INVALID_SOCKET) shutdown_socket(&(*ii));
                if ((ii = clients.erase(ii)) == clients.end()) break;
            }
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Re[26]: TCP IP очередь запросов...
От: CrystaX Россия https://crystax.me/
Дата: 20.05.05 13:07
Оценка:
Здравствуйте, -Cheese-, Вы писали:

C>Здравствуйте, CrystaX, Вы писали:


CX>>Вот здесь неверно. Тебе никто не гарантирует, что данные будут приходить кусками, не меньшими чем 2 или еще сколько байт. Теоретически возможна ситуация, когда данные вообще могут приходить по одному байту за одно чтение. В этом случае ты их потеряешь.


C>я думаю такого не случится.

C>сервера стоят рядом на одном хабе.

Это ничего не значит. Если на принимающей стороне переполнится буфер TCP, то эта ситуация возможна. А ты сам говоришь, что данные идут с высокой частотой.

CX>>Не факт, конечно, что это и единственный баг, но это точно надо исправить. Насчет же следующей функции (ListenSockets) — извини, не понял, что она должна делать. Никаких данных ты в ней не читаешь, так откуда же они берутся?

C>как не читаю...

C>
C>            if (FD_ISSET(*ii, &readfds) && !process_data(*ii)) {
C>                                toLog("Failed to read client");
C>                if (*ii != INVALID_SOCKET) shutdown_socket(&(*ii));
C>                if ((ii = clients.erase(ii)) == clients.end()) break;
C>            }
C>


Ок, понял. И где в твоей process_data проверка числа, находящегося в первых двух байтах?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[27]: TCP IP очередь запросов...
От: -Cheese-  
Дата: 20.05.05 13:18
Оценка:
Здравствуйте, CrystaX, Вы писали:

CX>Ок, понял. И где в твоей process_data проверка числа, находящегося в первых двух байтах?

так вот в этом-то и проблема.
я не знаю как обрабатывать полученное сообщение (если оно склеенное).
Делал так: повторил ситуацию, получил эту склейку (в режиме отладки исследовал её), смотрю и не знаю как её побороть..
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Re[28]: TCP IP очередь запросов...
От: CrystaX Россия https://crystax.me/
Дата: 20.05.05 13:41
Оценка:
Здравствуйте, -Cheese-, Вы писали:

C>Здравствуйте, CrystaX, Вы писали:


CX>>Ок, понял. И где в твоей process_data проверка числа, находящегося в первых двух байтах?

C>так вот в этом-то и проблема.
C>я не знаю как обрабатывать полученное сообщение (если оно склеенное).
C>Делал так: повторил ситуацию, получил эту склейку (в режиме отладки исследовал её), смотрю и не знаю как её побороть..

Нет, не так. Вот примерный код, как это должно выглядеть:
bool process_data(SOCKET sock)
{
    int received = 0, required = 2;
    while((received = recv(sock, buf + received, required - received, 0)) > 0);
    if(received == SOCKET_ERROR) return false;

    // Тут нужно особое внимание обратить на byte order. Если у тебя архитектура little-endian,
    // а значение высылается в сетевом порядке байт, то ntohs обязательна
    // short здесь в предположении что sizeof(short) == 2
    short size = ntohs(*reinterpret_cast<short *>(buf));
    
    required = size;
    received = 0;
    while((received = recv(sock, buf + received, required - received, 0)) > 0);
    if(received == SOCKET_ERROR) return false;
    
    buf[size] = '\0';
    pushToStack(buf, size);
    return true;
}
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[29]: TCP IP очередь запросов...
От: -Cheese-  
Дата: 20.05.05 13:54
Оценка:
Здравствуйте, CrystaX, Вы писали:

бррррр
а для чего ещё раз?

bool process_data(SOCKET sock)
{
    int received = 0, required = 2;
    while((received = recv(sock, buf + received, required - received, 0)) > 0);
    if(received == SOCKET_ERROR) return false;
    short size = ntohs(*reinterpret_cast<short *>(buf));
    
    required = size;
    received = 0;
    
        
        while((received = recv(sock, buf + received, required - received, 0)) > 0);
    if(received == SOCKET_ERROR) return false;
    
    
        buf[size] = '\0';
    pushToStack(buf, size);
    return true;
}
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Re[29]: TCP IP очередь запросов...
От: -Cheese-  
Дата: 20.05.05 14:00
Оценка:
CX> // Тут нужно особое внимание обратить на byte order. Если у тебя архитектура little-endian,
CX> // а значение высылается в сетевом порядке байт, то ntohs обязательна
CX> // short здесь в предположении что sizeof(short) == 2

приложение будет запускаться на 2000 винде
компилятор VC++
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Re[30]: TCP IP очередь запросов...
От: CrystaX Россия https://crystax.me/
Дата: 20.05.05 14:01
Оценка:
Здравствуйте, -Cheese-, Вы писали:

C>Здравствуйте, CrystaX, Вы писали:


C>бррррр

C>а для чего ещё раз?

Смотри:
Первые два    Оставшаяся часть
байта             сообщения
    |                 |
+--------+------------------------+
| xx  xx | xx  xx  xx  xx  xx  xx |
+--------+------------------------+


Чтобы узнать длину сообщения, нужно сначала прочитать первые два байта. Это первое чтение. Затем, зная длину — оставшуюся часть. Это второе чтение.
А цикл — это как раз гарантия того, что данные будут получены полностью, без потерь, причем столько, сколько нужно.

C>
C>bool process_data(SOCKET sock)
C>{
C>    int received = 0, required = 2;
C>    while((received = recv(sock, buf + received, required - received, 0)) > 0);
C>    if(received == SOCKET_ERROR) return false;
C>    short size = ntohs(*reinterpret_cast<short *>(buf));
    
C>    required = size;
C>    received = 0;
    
C>        
C>        while((received = recv(sock, buf + received, required - received, 0)) > 0);
C>    if(received == SOCKET_ERROR) return false;
C>    
    
C>        buf[size] = '\0';
C>    pushToStack(buf, size);
C>    return true;
C>}

C>
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[30]: TCP IP очередь запросов...
От: CrystaX Россия https://crystax.me/
Дата: 20.05.05 14:02
Оценка:
Здравствуйте, -Cheese-, Вы писали:

CX>> // Тут нужно особое внимание обратить на byte order. Если у тебя архитектура little-endian,

CX>> // а значение высылается в сетевом порядке байт, то ntohs обязательна
CX>> // short здесь в предположении что sizeof(short) == 2

C>приложение будет запускаться на 2000 винде

C>компилятор VC++

Важно не это, а то, в каком виде данные передает другая сторона.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[29]: TCP IP очередь запросов...
От: -Cheese-  
Дата: 24.05.05 06:05
Оценка:
Здравствуйте, CrystaX, если вы не против продолжим...:

CX>Нет, не так. Вот примерный код, как это должно выглядеть:

CX>
CX>bool process_data(SOCKET sock)
CX>{
CX>    int received = 0, required = 2;
CX>    while((received = recv(sock, buf + received, required - received, 0)) > 0);
CX>    if(received == SOCKET_ERROR) return false;

CX>    // Тут нужно особое внимание обратить на byte order. Если у тебя архитектура little-endian,
CX>    // а значение высылается в сетевом порядке байт, то ntohs обязательна
CX>    // short здесь в предположении что sizeof(short) == 2
CX>    short size = ntohs(*reinterpret_cast<short *>(buf));
    
CX>    required = size;
CX>    received = 0;
CX>    while((received = recv(sock, buf + received, required - received, 0)) > 0); 
CX>    if(received == SOCKET_ERROR) return false;
    
CX>    buf[size] = '\0';
CX>    pushToStack(buf, size);
CX>    return true;
CX>}
CX>


может я чего-то не понял, но по ходу функции в выделенном месте всегда получается, что received == SOCKET_ERROR
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[30]: TCP IP очередь запросов...
От: CrystaX Россия https://crystax.me/
Дата: 24.05.05 06:21
Оценка:
Здравствуйте, -Cheese-, Вы писали:

C>может я чего-то не понял, но по ходу функции в выделенном месте всегда получается, что received == SOCKET_ERROR


Обрати внимание на ntohs. Быть может, ее вызов здесь не нужен. Могу предположить такую ситуацию: данные передаются в little-endian виде, а ntohs их переворачивает. Впоне может получиться ситуация с отрицательным size. Тогда возможно возвращение SOCKET_ERROR. Других причин не вижу. Хотя, конечно, это может быть и наведенная ошибка. Не могу гадать.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[31]: TCP IP очередь запросов...
От: -Cheese-  
Дата: 24.05.05 07:02
Оценка:
Здравствуйте, CrystaX, Вы писали:

CX>Обрати внимание на ntohs. Быть может, ее вызов здесь не нужен. Могу предположить такую ситуацию: данные передаются в little-endian виде, а ntohs их переворачивает. Впоне может получиться ситуация с отрицательным size. Тогда возможно возвращение SOCKET_ERROR. Других причин не вижу. Хотя, конечно, это может быть и наведенная ошибка. Не могу гадать.


размер совпадает с передаваемым сообщением, смотрел..
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[32]: TCP IP очередь запросов...
От: CrystaX Россия https://crystax.me/
Дата: 24.05.05 07:06
Оценка:
Здравствуйте, -Cheese-, Вы писали:

C>Здравствуйте, CrystaX, Вы писали:


CX>>Обрати внимание на ntohs. Быть может, ее вызов здесь не нужен. Могу предположить такую ситуацию: данные передаются в little-endian виде, а ntohs их переворачивает. Впоне может получиться ситуация с отрицательным size. Тогда возможно возвращение SOCKET_ERROR. Других причин не вижу. Хотя, конечно, это может быть и наведенная ошибка. Не могу гадать.


C>размер совпадает с передаваемым сообщением, смотрел..


Ну тогда ищи, что еще сказать. Отладчик тебе в руки и вперед! А я не телепат. Угадать, что там происходит, не могу.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.