Re[15]: ::recv() и std::string
От: _chill Россия  
Дата: 01.12.04 23:12
Оценка:
Ребят, я вас, наверно, уже задолбал...
но как вам вот такой вариант send?
    void TcpSocket::send(const std::vector<char> &v_send)
    {
        int i_left = static_cast<int>(v_send.size());//количество оставшихся для отправки байт
        int idx = 0;//количество принятых байт
        int i_ret;//возвращаемое значение
        while(i_left > 0)
        {
            i_ret= ::send(sock, &v_send[idx], i_left, NULL);
            if(i_ret == SOCKET_ERROR)
            {
                throw(SocketExeption("Can't send"));
            }
            i_left -= i_ret;
            idx += i_ret;
        }
    }

у меня он был сделан как
void TcpSocket::send(const std::string &str_send);

но я подумал, что с бинарными данными такое не прокатит, т.ч. пришлось изменить немного определение...
правильно ли это или нет?


в программе немного неудобно теперь этим пользоваться...
зато можно будет бинарные данные корректно посылать...
        TcpSocket sock;
    std::vector<char> vec(12);
    memcpy((&vec[0]), "USER chill\r\n", 12);
    sock.send(vec);
Re[2]: ::recv() и std::string
От: MaximE Великобритания  
Дата: 16.03.05 00:06
Оценка:
Здравствуйте, zelyony, Вы писали:

Z>сколько байт можно прочитать не блокируясь помогает узнать

Z>
Z>u_long availBytes = 0;
Z>int wsaRes = ioctlsocket( hSocket, FIONREAD, &availBytes);
Z>// обработка результата
Z>// если не было ошибки, в availBytes - кол-во байт лежащих в буфере и которые можно прочитать не блокируясь
Z>// в линухе вроде просто ioctcl(..)
Z>// для датаграммных сокетов возвращается также кол-во доступных, но считывать придётся по-"датаграммно". система сама будет возвращать данные таким образом, к тому что, за один раз пару датаграмм не считать
Z>


Проблема в том, что ты не можешь сделать этот вызов атомарным (в контексте одного потока выполнения) с последующими одним и несколькими вызовами. После этой самой строчки мог произойти context switch, после которого в приемном буфере сокета появилось еще больше данных. И ты никак не можешь ни отследить этот момент, ни предотвратить. По сути, единственное, что надежно определяет этот вызов, это то, есть ли в буфере данные или нет, но не сколько конкретно их. Именно эту задачу определения наличия данных выполняют вызовы select() и poll().

Вопрос: что делать с полученным значением, когда оно может быть полезным?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.