WebSocket的C 伺服器端實現

2021-07-23 22:53:57 字數 2728 閱讀 1925

**

由於需要在專案中增加websocket協議,與客戶端進行通訊,不想使用開源的庫,比如websocketpp,就自己根據websocket協議實現一套函式,完全使用c++實現。

一、原理

websocket協議解析,已經在前面部落格裡面詳細講解過,可以參考部落格這裡就不詳細細說。

伺服器端實現就是使用tcp協議,使用傳統的socket流程進行繫結監聽,使用epoll控制多路併發,收到websocket握手包時候進行握手處理,握手成功便可進行資料收發。

二、實現

1、伺服器監聽

該部分使用的是tcp socket流程,首先是通過socket函式建立socket,通過bind函式繫結到某個埠,本例使用的是9000,然後通過listen函式開啟監聽,**如下:

listenfd_ = socket(af_inet, sock_stream, 0

);

if(listenfd_ == -1

)

struct

sockaddr_in server_addr;

memset(&server_addr, 0, sizeof

(sockaddr_in));

server_addr.sin_family =af_inet;

server_addr.sin_addr.s_addr =htonl(inaddr_any);

server_addr.sin_port =htons(port);

if(-1 == bind(listenfd_, (struct sockaddr *)(&server_addr), sizeof

(server_addr)))

if(-1 == listen(listenfd_, 5

))

2、epoll控制多路併發

該部分使用的是epoll流程,首先在初始化時候使用epoll_create建立epoll控制代碼

epollfd_ = epoll_create(1024);
然後通過epoll_wait等待fd事件來臨,當監聽到是listenfd事件時候,說明是客戶端連線伺服器,就使用accept接受連線,然後註冊該連線epollin事件,當epoll監聽到epollin事件時候,即可進行握手和資料讀取。**如下:

void ctl_event(int fd, bool

flag)

else

}

int

epoll_loop()

else

if(events[i].events &epollin)

else}}

}return0;

}

3、websocket握手連線

握手部分主要是根據websocket握手包進行解析,然後根據sec-websocket-key進行sha1雜湊,生成相應的key,返回給客戶端,與客戶端進行握手。**如下:

//該函式是獲取websocket握手包的資訊,按照分割字元進行解析

//該函式是根據websocket返回包的格式拼接相應的返回包

void parse_str(char *request)

server_key = base64_encode(reinterpret_cast(message_digest),20

); server_key += "

\r\n";

strcat(request, server_key.c_str());

strcat(request,

"upgrade: websocket\r\n\r\n");

}

4、資料讀取

當伺服器與客戶端握手成功後,就可以進行正常的通訊,讀取資料了。使用的是tcp協議的方法,解析websocket包根據協議格式,在前面部落格裡面有詳細分析,這裡只把實現**貼出來。

int fetch_websocket_info(char *msg)

int fetch_fin(char *msg, int &pos)

int fetch_opcode(char *msg, int &pos)

int fetch_mask(char *msg, int &pos)

int fetch_masking_key(char *msg, int &pos)

int fetch_payload_length(char *msg, int &pos)

else

if(payload_length_ == 127

)

return0;

}int fetch_payload(char *msg, int &pos)

else

}pos +=payload_length_;

return0;

}

WebSocket的C 伺服器端實現

由於需要在專案中增加websocket協議,與客戶端進行通訊,不想使用開源的庫,比如websocketpp,就自己根據websocket協議實現一套函式,完全使用c 實現。一 原理 websocket協議解析,已經在前面部落格裡面詳細講解過,可以參考部落格這裡就不詳細細說。伺服器端實現就是使用tcp...

WebSocket伺服器端的日誌重複列印問題

日誌中backend ms與webshop的每次通訊,require,response都是只有一次記錄,截圖來自log latestbackend with oldfrontend 但是backend ms和simulator的通訊,request和response的記錄都不止一次,比如confir...

socket伺服器端

伺服器 include winsock2.h include string.h include stdio.h include time.h include stdarg.h include stdlib.h pragma comment lib,ws2 32 void errexit const ...