借鑑的 https://blog.csdn.net/qq_19004627/article/details/88737411
坑1:openssl報錯:ip address mismatch(preverify_ok=0;err=64;depth=0),不確定是不是自己生成的證書在無網情況下是不是不可用(開發電腦無法連網際網路),暫時遮蔽了openssl相關的程式碼。
坑2:這個文章的client的程式碼中的傳送程式碼有中文“你好”,導致伺服器解析異常,進而斷鏈(這個問題,困擾了我幾乎一整天)。暫時修改成非中文,如果一定要中文,需要轉utf-8。
坑3:伺服器的回顯程式碼可以做下最佳化。如下所示,當data->len非零時再傳輸。
case LWS_CALLBACK_SERVER_WRITEABLE: // 當此連線可寫時 { if (data->len != 0) { lws_write(wsi, &data->buf[LWS_PRE], data->len, LWS_WRITE_TEXT); data->len = 0; } }
坑4:接收字串列印亂碼(直接列印in),可以在長度後面增加\0。
case LWS_CALLBACK_RECEIVE: // 當接收到客戶端發來的幀以後
// 判斷是否最後一幀
data->fin = lws_is_final_fragment(wsi);
// 判斷是否二進位制訊息
data->bin = lws_frame_is_binary(wsi);
// 對伺服器的接收端進行流量控制,如果來不及處理,可以控制之
// 下面的呼叫禁止在此連線上接收資料
//lws_rx_flow_control(wsi, 0);
// 業務處理部分,為了實現Echo伺服器,把客戶端資料儲存起來
memcpy(&data->buf[LWS_PRE], in, len);
data->len = len;
data->buf[LWS_PRE + data->len] = 0;
lwsl_notice("recvied message:%s,len=%d\n", (char*)&data->buf[LWS_PRE], data->len);
// 需要給客戶端應答時,觸發一次寫回撥
lws_callback_on_writable(wsi);
break;
其他今天搜尋了一天的資料的心得:
1、lws_write前面一定要預留LWS_PRE的空間,給lws內部使用,否則會崩潰。
2、如果報文很長,需要分片,需要判斷lws_is_final_fragment,可以使用類似下面的程式碼:
case LWS_CALLBACK_RECEIVE: { Client * const client = (Client *)user; const size_t remaining = lws_remaining_packet_payload(wsi); if (!remaining && lws_is_final_fragment(wsi)) { if (client->HasFragments()) { client->AppendMessageFragment(in, len, 0); in = (void *)client->GetMessage(); len = client->GetMessageLength(); } client->ProcessMessage((char *)in, len, wsi); client->ResetMessage(); } else client->AppendMessageFragment(in, len, remaining); } break;
3、客戶端支援多連線到不同伺服器,需要開多個執行緒去處理。
其他的一些可以參考https://blog.csdn.net/yetyongjin/article/details/131082375