以下使用到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
--- 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超时后添加发送函数。
到此完毕,谢谢欣赏