8266做websocket server

来源:互联网 发布:申通快递淘宝价格表 编辑:程序博客网 时间:2024/06/05 13:36
以下使用到nopoll,使用教程及其api请查看http://www.aspl.es/nopoll/
espressif官网提供开发环境lubuntu;
espressif官网提供的 ESP8266 RTOS SDK V1.5.0自带websocket库可用但,发现不能正常建立listener、建立websocket server后client不能正常建立通信。。。可能是只是为了做client的吧(只能这么想了),自己重新编译nopoll开始找问题原因:
建立listener时调用nopoll_listener_new函数报错,根据错误消息跟踪下去发现fd = socket(AF_INET, SOCK_STREAM, 0);返回的句柄是0。。。 linux中0,1,2都是做stdin stdout stderr用的但这个单片机又没有这些,开始修改有两个办法:(这里还有个问题fd=3时也不能正常运行必须大于3,原因未知)
办法1、在socket(AF_INET, SOCK_STREAM, 0)函数前多几次socket不就可以让需要的fd值大于2了吗,哈哈哈


办法2、在socket跟踪下去找到lwip_socket中alloc_socket函数修改起始i=4,如下


可以建立server了,但同样有问题但因为不知道是个问题因为没有warning或error。。。(郁闷)
问题分析:select时返回-1但errno取没有相应的错误标志。。。只能心里fuck
不用自带lwip库自己重新编译lwip修改之。。。。

nopoll可能是用的人少,不能正常建立通信的问题没有百度谷歌出来。。。默默打开wireshark自己分析。
现象如下

switching包后面tcp就开始三次挥手断开连接,考虑Sec-WebSocket-Accept异常
分析switching包发现果然base64计算不正常,修改nopoll_conn.c中nopoll_conn_produce_accept_key函数:
。。。。

    +++ unsigned char dev_sha1sum[20];
    +++ mbedtls_sha1_context dev_ctx;
    +++ mbedtls_sha1_init( &dev_ctx );
    +++ mbedtls_sha1_starts( &dev_ctx );
    +++ mbedtls_sha1_update( &dev_ctx, accept_key, strlen (accept_key) );
    +++ mbedtls_sha1_finish( &dev_ctx, dev_sha1sum );
    +++ md_len=20;
    /* now convert into base64 */
    +++ if (! nopoll_base64_encode ((const char *) dev_sha1sum, md_len, (char *) accept_key, &accept_key_size)) {
    +++     nopoll_log (ctx, NOPOLL_LEVEL_CRITICAL, "Failed to base64 sec-websocket-key value..");
    +++     return NULL;
    +++ }
    +++ printf("Returning Sec-Websocket-Accept: %s\n", accept_key);
    +++ nopoll_log (ctx, NOPOLL_LEVEL_DEBUG, "Returning Sec-Websocket-Accept: %s", accept_key);

    /* now sha-1 */
    --- md = (EVP_MD *)EVP_sha1 ();
    --- EVP_DigestInit (&mdctx, md);
    --- EVP_DigestUpdate (&mdctx, accept_key, strlen (accept_key));
    --- EVP_DigestFinal (&mdctx, buffer, &md_len);

    --- int i=0;
    --- printf("buffer:");
    --- for(i=0;i<EVP_MAX_MD_SIZE;i++)
    ---     printf("%x ",buffer[i]);
    --- printf(" md_len=%u \naccept_key:%s accept_key_size=%u Sha-1 length is: %u\n",  md_len , accept_key, accept_key_size, md_len);
    --- nopoll_log (ctx, NOPOLL_LEVEL_DEBUG, "Sha-1 length is: %u", md_len);
    /* now convert into base64 */
    --- if (! nopoll_base64_encode ((const char *) buffer, md_len, (char *) accept_key, &accept_key_size)) {
    ---     nopoll_log (ctx, NOPOLL_LEVEL_CRITICAL, "Failed to base64 sec-websocket-key value..");
    ---     return NULL;
    --- }
    --- printf("Returning Sec-Websocket-Accept: %s\n", accept_key);
    --- nopoll_log (ctx, NOPOLL_LEVEL_DEBUG, "Returning Sec-Websocket-Accept: %s", accept_key);
。。。。

这样就能正常建立连接使用网页的websocket client正常通信,呵呵呵
但新的问题又来了,一个client发送建立连接后不发送任何数据就会一直阻塞,不会处理其它client的建立请求,这个问题最好处理设置tcp超时就好了。
吧啦吧啦写逻辑。。。
最后需要server主动发送数据给所有client,这是websocket server基本技能但是nopoll没有这样的api。。。。自己动手。。
找到nopoll_loop_wait在wait超时后添加发送函数。
到此完毕,谢谢欣赏
原创粉丝点击