首页 > 解决方案 > SSL_read 无法读取服务器发送的所有字节

问题描述

我已经实现了服务器-客户端模型。我想向客户端发送大字节数据(大约 9000 字节)。出于试用目的,仅从服务器向客户端发送 2264 字节。

服务器代码:

int Send()
{
strcpy(FinalOutput,"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");
LenFinalOutput = 2264;
int r = 0;
r=SSL_write(ssl, FinalOutput, LenFinalOutput);
}

这里 FinalOutput 在 SSL_write 之前打印,它包含所有数据, LenFinalOutput 包含长度。r 发送后的值为 2264,表示所有字节都是从服务器发送的。

在客户端仅接收 2047 个字节。并且 SSL_pending 返回 0。

客户端代码:

接收缓冲区的大小为 5000 字节。如果从服务器发送了 2047 个字节,那么它将接收客户端上的所有字节。但是如果发送的字节数超过 2047 个,则会收到十六进制数据,其中偶数字节不一致,例如 487,5。

int sslRead(SSLCon* con, char *data, int size, int timeoutMs) {
char *buf=NULL;
int rd = 0;
int r = 1;
ST_TIMER timer = {0,0,0};
if(!con || !data || !size)
{
    return SSLERR;
}

buf = (char *)malloc(size);
OsTimerSet(&timer, timeoutMs);

PrnLog(LOG_DEBUG,"size %d,%d",size,buf);

int flags = fcntl(con->socket, F_GETFL, 0);
fcntl(con->socket, F_SETFL, flags | O_NONBLOCK);

while (rd < size && r)
{
    int iPending = SSL_pending(con->sslHandle);
    if(rd > 0 && iPending == 0)
        break;

    r = SSL_read(con->sslHandle, buf + rd, size);

    if (r <= 0) {
        int err = SSL_get_error(con->sslHandle, r);
        if (err == SSL_ERROR_WANT_READ ||
            err == SSL_ERROR_WANT_WRITE) {
            continue;
        }
        //ERR_print_errors_fp(stderr);
        PrnLog(LOG_ERROR, "SSL_read ret %d true:%d errno:%ul socket:%d\n",
            r, SSL_get_error(con->sslHandle, r), ERR_get_error(), con->socket);
    }
    if(r < 0)
    {
        free(buf);
        fcntl(con->socket, F_SETFL, flags &(~O_NONBLOCK));
        return SSLERR;
    }

    PrnLog(LOG_ERROR, "read %d bytes\n", r);

    rd += r;

    if(rd >= size)
        break;
}
PrnLog(LOG_ERROR, "read %d bytes contents:\n%.*s\n", rd, rd, buf);

memcpy(data, buf, rd);

free(buf);
fcntl(con->socket, F_SETFL, flags &(~O_NONBLOCK));
return rd;

}

标签: ssl

解决方案


推荐阅读