网上找了个websocket的代码 不过只提供了服务端的处理, 对于客户端握手 以及订阅等进行了补充开发,实现了相关功能
void parse_str(char *request){
char KEY[20]="y2g8E-f^3Bxc";
time_t curtime=0;
char sTimeStr[64];
int len;
char acDigest[65] = {0};
char acHex[129] = {0};
strcat(request, "GET / HTTP/1.1\r\n");
strcat(request, "Connection:Upgrade\r\n");
strcat(request, "Host:127.0.0.1:8088\r\n");
strcat(request, "Origin:null\r\n");
strcat(request, "Sec-WebSocket-Extensions:x-webkit-deflate-frame\r\n");
strcat(request, "Sec-WebSocket-Key:");
time(&curtime);
memset(sTimeStr, 0, sizeof(sTimeStr));
sprintf(sTimeStr,"%lld", curtime);
len=strlen(sTimeStr);
memset(acHex,0, sizeof(acHex));
CMD5 m_oMD5;
m_oMD5.Reset();
m_oMD5.AddData(sTimeStr, len);
m_oMD5.FinalDigest(acDigest);
Binary2Hex(reinterpret_cast<unsigned char*>(acDigest), 16, acHex);
char second_md5[128];
memset(second_md5, 0, sizeof(second_md5));
strcpy(second_md5, acHex);
strcat(second_md5, KEY);
memset(acDigest,0, sizeof(acDigest));
memset(acHex,0, sizeof(acHex));
len=strlen(second_md5);
m_oMD5.Reset();
m_oMD5.AddData(second_md5, len);
m_oMD5.FinalDigest(acDigest);
Binary2Hex(reinterpret_cast<unsigned char*>(acDigest), 16, acHex);
strcat(request, acHex);
strcat(request, "==\r\n");
strcat(request, "Sec-WebSocket-Version:13\r\n");
strcat(request, "Upgrade:websocket\r\n\r\n");
}
int Websocket_Request::combile_request(char *msg, char* reqdata ){
uint16_t length=0;
int pos=0;
fin_=0x81; // 单帧 字符串模式传输
mask_=0x80; //客户端请求必须使用掩码
memcpy(msg+pos, &fin_, 1);
pos++;
payload_length_=strlen(reqdata);
/*负载数据”的长度,以字节为单位:如果0-125,这是负载长度。如果126,之后的两字节解释为一个16位的无符号整数是负载长
度。如果127,之后的8 字节解释为一个64位的无符号整数(最高有效位必须是0)是负载长度。
多字节长度数量以网络字节顺序来表示。 */
if(payload_length_ > 126) //现有业务不会需要用到4字节的数据长度 按最大两个字节长度处理
{
memset(msg+pos, 0xFE, 1);
pos++;
length=htons(payload_length_);
memcpy(msg+pos, &length, 2);
pos++;
pos++;
}
else
{
length=mask_+ payload_length_;
memcpy(msg+pos, &length, 1);
pos++;
}
masking_key_[0]='A';
masking_key_[1]='C';
masking_key_[2]='D';
masking_key_[3]='b';
memcpy(msg+pos, masking_key_, 4);
pos += 4;
int j ;
uint i = 0;
for( i = 0; i < payload_length_; i++){
j = i % 4;
msg[pos + i] =reqdata[i] ^ masking_key_[j];
}
printf("WEBSOCKET PROTOCOL\n"
"FIN: %d\n"
"OPCODE: %d\n"
"MASK: %d\n"
"PAYLOADLEN: %d\n"
"PAYLOAD: %s",
fin_, opcode_, mask_, payload_length_, msg);
return 0;
}