Как исправить «SSL_Read () иногда не читает полный пакет в случае специальных символов в начале» - PullRequest
1 голос
/ 10 апреля 2019

История вопроса: • Иногда Пакет ответа от Сервера не принимается на Клиенте.• Когда мы проверяем из SSL_read (...), количество прочитанных байтов не совпадает с ожидаемой длиной пакета (во много раз длина считываемого байта равна 1) • Но когда мы повторяем ответ «Отправка и чтение», из 10 размы получаем эту проблему ~ 4 раза.

Подробности: • Сервер отправил данные ниже, а поведение SSL_read - ниже.• 5 апреля 12:45:57 rstServertest XLOG: VNAC [01] 82 c5 b4 2e 41 39 39 39 39 39 .E4.A99999 => SSL_read () считывает все данные.• 5 апреля 10:30:49 rstServertest XLOG: VNAC [01] 60 22 00 40 00 82 c5 b4 2e 41 `". @ .. E4.A => SSL_read () чтение только один байт (пробел), остальные данныеотсутствует даже после многократного вызова SSL_read ().

Пожалуйста, дайте мне знать причину этой проблемы и ее решение.

// try connect if not connected
if(mConnected != true && Connect()) {
    LOGE("connection fail");
    return PERR_NET_CONNECT;
}

timeval start;
gettimeofday(&start, NULL);

int remain = *len;

do {
    LOGC("Recv loop");
    int remainTo = timeoutInMs - TimeElapsed(start, MILLISEC_SCALE);
    LOGD("remain To %d", remainTo);
    if(remainTo <= 0) // timeout
        break;

    fd_set readfds;
    FD_ZERO(&readfds);
    FD_SET(mSd, &readfds);
    timeval timeout;
    timeout.tv_sec = remainTo / 1000; // milli sec to seconds
    timeout.tv_usec = (remainTo % 1000) * 1000;
    int r = select(mSd+1, &readfds, 0, 0, &timeout);

    if(r != 0 && FD_ISSET(mSd, &readfds)) { // something came
        r = SSL_read(mSslConn, buf, remain);
        char buffer[512] = {0,};
        memcpy(buffer,buf,remain);

        int sslErr = SSL_get_error(mSslConn, r);
        LOGD("sslErr=%d",sslErr);
        switch(sslErr) {
            case SSL_ERROR_NONE:
                buf += r;
                remain -= r;
                LOGC("read %d", r);
                break;
            case SSL_ERROR_WANT_WRITE:
            case SSL_ERROR_WANT_READ:
                LOGC("SSL_ERROR_WANT_READ/WRITE");
                usleep(1000*10); // sleep 10ms ?
                break;
            default: {
                Disconnect();
                LOGE("SSL_read %d", sslErr);
                return PERR_NET_READ;
            }
        }
    }
} while(remain > 0);

*len -= remain;
return 0;

Мне нужно прочитать данные полного буфера, отправленные сСервер.

...