devC2/c++/devC/devC2/WebsocketConfig.c

152 lines
4.2 KiB
C

#include "WebsocketConfig.h"
#include <Winsock2.h>
#include "Transcoding.h"
int websocket_connect(Websocket *ws, const char *address){
// 解析URL
char host[BUF_SIZE], path[BUF_SIZE];
int port = 80;
char *url = (char *)malloc(sizeof(char) * 100);
memset(url, 0, sizeof(url));
if(strlen(address) == 0) {
url = (char *)"ws://127.0.0.1:10088/cxx";
} else {
strcpy(url, address);
}
if (sscanf(url, "ws://%[^:/]:%d/%s", host, &port, path) != 3) {
if (sscanf(url, "ws://%[^:/]:%d", host, &port) != 2) {
return -1;
}
}
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2),&wsaData) != 0) {
printf("winsock连接失败");
return -1;
}
// 建立TCP连接
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.S_un.S_addr = inet_addr(host);
int result = connect(sockfd, (SOCKADDR*)&addr, sizeof(SOCKADDR));
if (result < 0) {
closesocket(sockfd);
return -1;
}
// 发送WebSocket握手请求
sprintf(ws->buf, "GET /%s HTTP/1.1\r\n", path);
sprintf(ws->buf + strlen(ws->buf), "Host: %s:%d\r\n", host, port);
sprintf(ws->buf + strlen(ws->buf), "Connection: Upgrade\r\n");
sprintf(ws->buf + strlen(ws->buf), "Pragma: no-cache\r\n");
sprintf(ws->buf + strlen(ws->buf), "Cache-Control: no-cache\r\n");
sprintf(ws->buf + strlen(ws->buf), "Upgrade: websocket\r\n");
sprintf(ws->buf + strlen(ws->buf), "Sec-WebSocket-Version: 13\r\n");
sprintf(ws->buf + strlen(ws->buf), "Accept-Encoding: gzip, deflate\r\n");
sprintf(ws->buf + strlen(ws->buf), "Accept-Language: zh-CN,zh;q=0.9\r\n");
sprintf(ws->buf + strlen(ws->buf), "Sec-WebSocket-Version: 13\r\n");
sprintf(ws->buf + strlen(ws->buf), "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n");
sprintf(ws->buf + strlen(ws->buf), "Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n");
sprintf(ws->buf + strlen(ws->buf), "\r\n");
if (send(sockfd, ws->buf, strlen(ws->buf), 0) < 0) {
closesocket(sockfd);
return -1;
}
// 接收WebSocket握手响应
int n = recv(sockfd, ws->buf, BUF_SIZE, 0);
if (n < 0) {
closesocket(sockfd);
return -1;
}
ws->buf[n] = '\0';
//HTTP/1.1 101 Switching Protocols
if (strstr(ws->buf, "HTTP/1.1 101") == NULL) {
closesocket(sockfd);
return -1;
}
// WebSocket连接建立成功
ws->sockfd = sockfd;
return 0;
}
//const char* parseObject(UAV uav) {
// char *json_str = (char *)malloc(sizeof(char) * 100); // 假设 JSON 字符串最大长
//// sprintf(json_str, "{\"number\":\"%i\",\"event_id\":\"%i\",\"pos\":%s,\"type\":%s,\"commond\":%s}"
//// ,uav.number, uav.event_id,"[0.0,0.0]", uav.type, uav.commond);
// sprintf(json_str, "{\"event_id\":\"%i\",\"type\":%s,\"commond\":%s}"
// , uav.event_id, uav.type, uav.commond);
// return json_str;
//}
int websocket_recv() {
// 接收响应消息
char recvMsg[1024];
memset(recvMsg, 0, sizeof(recvMsg));
int recvLen = recv(websocket.sockfd, recvMsg, sizeof(recvMsg)-1, 0);
printf("收到响应消息长度:%i",recvLen);
if (recvLen == SOCKET_ERROR || recvLen == 0) {
printf("接收响应消息失败\n");
return -1;
}
recvMsg[recvLen] = '\0';
// char* abc = UTF8ToANSI(recvMsg);
printf("收到响应消息:%s",recvMsg);
return recvLen;
}
int websocket_send(const char *data, int len) {
// 构造WebSocket数据帧
char frame[BUF_SIZE];
frame[0] = 0x81;
frame[1] = (0x80 | len);
frame[2] = 0x12;
frame[3] = 0x34;
frame[4] = 0x56;
frame[5] = 0x78;
int i;
for (i = 0; i < len; i++) {
frame[i + 6] = data[i] ^ frame[i%4+2];
}
if (send(websocket.sockfd, frame, strlen(frame), 0) < 0) {
return -1;
}
return 0;
}
void sendMessage(const char *data) {
printf(data);
if (websocket_send(data,strlen(data)) < 0) {
printf("WebSocket发送数据失败\n");
websocket_close();
}else{
printf("WebSocket发送数据成功呢\n");
getChoose();
}
}
void websocket_close() {
closesocket(websocket.sockfd);
printf("子线程已销毁,通信已关闭");
}
void createPthread() {
// 创建接收消息的线程
if (pthread_create(&reply_thread, NULL, websocket_recv, NULL) != 0) {
// printf("创建接收消息线程失败");
exit(1);
}else {
// printf("创建接收消息线程成功");
}
}