**
由於需要在專案中增加websocket協議,與客戶端進行通訊,不想使用開源的庫,比如websocketpp,就自己根據websocket協議實現一套函式,完全使用c++實現。
一、原理
websocket協議解析,已經在前面部落格裡面詳細講解過,可以參考部落格這裡就不詳細細說。
伺服器端實現就是使用tcp協議,使用傳統的socket流程進行繫結監聽,使用epoll控制多路併發,收到websocket握手包時候進行握手處理,握手成功便可進行資料收發。
二、實現
1、伺服器監聽
該部分使用的是tcp socket流程,首先是通過socket函式建立socket,通過bind函式繫結到某個埠,本例使用的是9000,然後通過listen函式開啟監聽,**如下:
listenfd_ = socket(af_inet, sock_stream, 02、epoll控制多路併發);
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
))
該部分使用的是epoll流程,首先在初始化時候使用epoll_create建立epoll控制代碼
epollfd_ = epoll_create(1024);然後通過epoll_wait等待fd事件來臨,當監聽到是listenfd事件時候,說明是客戶端連線伺服器,就使用accept接受連線,然後註冊該連線epollin事件,當epoll監聽到epollin事件時候,即可進行握手和資料讀取。**如下:
void ctl_event(int fd, boolflag)
else
}
int3、websocket握手連線epoll_loop()
else
if(events[i].events &epollin)
else}}
}return0;
}
握手部分主要是根據websocket握手包進行解析,然後根據sec-websocket-key進行sha1雜湊,生成相應的key,返回給客戶端,與客戶端進行握手。**如下:
//該函式是獲取websocket握手包的資訊,按照分割字元進行解析//該函式是根據websocket返回包的格式拼接相應的返回包4、資料讀取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");
}
當伺服器與客戶端握手成功後,就可以進行正常的通訊,讀取資料了。使用的是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 ...