由於需要在專案中增加websocket協議,與客戶端進行通訊,不想使用開源的庫,比如websocketpp,就自己根據websocket協議實現一套函式,完全使用c++實現。
一、原理
websocket協議解析,已經在前面部落格裡面詳細講解過,可以參考部落格這裡就不詳細細說。
伺服器端實現就是使用tcp協議,使用傳統的socket流程進行繫結監聽,使用epoll控制多路併發,收到websocket握手包時候進行握手處理,握手成功便可進行資料收發。
二、實現
1、伺服器監聽
該部分使用的是tcp socket流程,首先是通過socket函式建立socket,通過bind函式繫結到某個埠,本例使用的是9000,然後通過listen函式開啟監聽,**如下:
listenfd_ = socket(af_inet, sock_stream, 0);2、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, bool flag)else
}
int epoll_loop()3、websocket握手連線else if(events[i].events & epollin)
else}}
}return 0;
}
握手部分主要是根據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)5、總結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)
return 0;
}int fetch_payload(char *msg, int &pos)
else
}pos += payload_length_;
return 0;
}
到此為止,完整實現了使用c++對websocket協議進行解析,握手,資料收發,不借助開源庫就實現了websocket相關功能,最大程度的與專案儲存相容。
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 ...