美文网首页
HTTP/1.1,Select 与 SSL_read

HTTP/1.1,Select 与 SSL_read

作者: 李书文 | 来源:发表于2017-01-10 14:07 被阅读904次

要写一个简单的WebSocket客户端,在写的过程中手贱于是重写了所有的Socket,TCP,SSL和HTTP的代码。因为原来的HTTP只是一个简单的HTTP/1.0的客户端,为了让能给WebSocket使用,决定对HTTP/1.1进行有限的支持。

在开发HTTP/1.1的时候遇到一个问题:Request发送出去之后,迟迟收不到Response。查找了半天发现因为WebSocket是一个长连接和原来的HTTP/1.0的一锤子买卖不一样。原有的处理逻辑是一直read,直到Socket连接断开就可以了。但是对于一个长连接来说这种处理方法显然是不合适的。

借鉴了很多的HTTP Client的代码,后来选择在recv的过程中就把HTTP Response给处理了,对Header以及Content进行分别处理。然后发现可以一次recv一个Byte,这样处理起来很方便,而且逻辑很顺畅。

前面已经测试完毕了,但是挂到环境里一测试又出问题了,还是Response收不到。原因是Select和SSL_read不太兼容导致的。代码中为了能加入timeout,所以在所有读写之前都进行了Select:

   int ret = select (....);
   if (ret > 0) {
     SSL_read(...)/SSL_write(...)/ recv(...)/ send(...);
   }

这里有一个问题,因为每一次都只收1 byte。在之前测试时用的是recv,没有问题。但是在用SSL_read的时候,再进行select就会超时。想了半天,可能是SSL_read会一次把Tcp的Buffer读进来,从而导致下次select的时候可能没有数据了,也就超时了。实际测试发现这个猜测是对的。怎么办呢?解决方案是请SSL_pending出马,这个函数可以检测目标SSL中到底有多少可读数据。那么在Select之前先用它来做一次测试,这样就解决了有数据却读不出来的问题。最后贴上真实的代码,以备后用。

int Tls::recv(char * buf, int len) {
    if (ssl == NULL) {
        return Socket::recv(buf, len);
    }

    if (buf == NULL || len <= 0) {
        err = ERR_PARAM_NULL;
        return -1;
    }

    int pending = SSL_pending(ssl);
    if (pending <= 0) {
        if (!blocking) {
            if (waitReadable(timeout) < 0) {
                return -1;
            }
        }
    }

    if (pending > 0 && len > pending) {
        len = pending;
    }

    int ret = SSL_read(ssl, buf, len);
    if (ret <= 0) {
        sslerr = SSL_get_error(ssl, ret);
        if (sslerr == SSL_ERROR_WANT_READ) {
            err = ERR_TLS_WANT_READ;
        }
    }

    return ret;
}

相关文章

  • HTTP/1.1,Select 与 SSL_read

    要写一个简单的WebSocket客户端,在写的过程中手贱于是重写了所有的Socket,TCP,SSL和HTTP的代...

  • select深入理解

    1 数据结构与函数原型 1.1 select 函数原型 头文件select位于:#include struct ...

  • HTTP的区别

    HTTP1.0、HTTP1.1和HTTP2.0区别 1. HTTP1.0与HTTP1.1 1.1 长连接 HTTP...

  • day04(select)

    1、select 1.1、 作用 1.2、单独使用select 1.2.1、select @@xxxx; 获取参...

  • MySQL 之SELECT ... INTO OUTFILE与L

    一. SELECT ... INTO OUTFILE语句简介 1.1 SELECT ... INTO OUTFIL...

  • Http 1.1

    200 请求已成功,请求所希望的响应头或数据体将随此响应返回。 301 被请求的资源已永久移动到新位置,并且将来任...

  • HTTP/1.1

    HTTP\1.1 是在 HTTP\1.0 的基础上做了一些改进 持久连接 在 HTTP\1.0 中,每进行一次 H...

  • Day04-SQL基础应用+select练习

    DQL使用 1. select 1.1 作用 1.2 单独使用select 1.2.1 select @@xxxx...

  • HTTP1.0与HTTP1.1

    什么是HTTP? HTTP 是一种协议,允许 web 服务器和浏览器通过互联网进行来发送和接受数据。它是一...

  • HTTP1.1与2.0

    1.多路复用 在 HTTP/1.1 协议中 「浏览器客户端在同一时间,针对同一域名下的请求有一定数量限制。超过限制...

网友评论

      本文标题:HTTP/1.1,Select 与 SSL_read

      本文链接:https://www.haomeiwen.com/subject/mevkbttx.html