当前位置:   article > 正文

嵌入式设备websocket实现_嵌入式websocket

嵌入式websocket

以下是使用 jQuery 实现 WebSocket 连接的基本示例代码:

  1. // 声明 websocket 变量
  2. var webSocket;
  3. // 与服务器建立连接
  4. function connect() {
  5. webSocket = new WebSocket("ws://localhost:8080");
  6. // 连接成功时触发的事件
  7. webSocket.onopen = function(event) {
  8. console.log("WebSocket连接已建立");
  9. };
  10. // 接收到消息时触发的事件
  11. webSocket.onmessage = function(event) {
  12. console.log("接收到消息:" + event.data);
  13. };
  14. // 连接关闭时触发的事件
  15. webSocket.onclose = function(event) {
  16. console.log("WebSocket连接已关闭");
  17. };
  18. // 发生错误时触发的事件
  19. webSocket.onerror = function(event) {
  20. console.log("WebSocket连接发生错误");
  21. };
  22. }
  23. // 向服务器发送消息
  24. function sendMsg() {
  25. var msg = $("#msg").val();
  26. webSocket.send(msg);
  27. }
  28. // 关闭 WebSocket 连接
  29. function closeWebSocket() {
  30. webSocket.close();
  31. }
  32. // 初始化函数
  33. $(document).ready(function() {
  34. $("#connectBtn").click(function() {
  35. connect();
  36. });
  37. $("#sendBtn").click(function() {
  38. sendMsg();
  39. });
  40. $("#closeBtn").click(function() {
  41. closeWebSocket();
  42. });
  43. });

上述代码中,我们声明了 webSocket 变量用来保存 WebSocket 连接对象,然后定义了 connect()sendMsg()closeWebSocket() 三个方法分别用来建立连接、发送消息和关闭连接。在初始化函数中,我们使用 jQuery 的 click() 方法来绑定按钮的点击事件,然后分别调用上述三个方法。

需要注意的是,以上代码仅为示例代码,实际使用时需要根据具体情况进行修改。在使用 WebSocket 通信时,还需要注意跨域访问等问题。

以下是使用C语言实现嵌入式设备开发websocket的示例代码,该代码为设备端作为server端与网页进行交互:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <errno.h>
  5. #include <unistd.h>
  6. #include <fcntl.h>
  7. #include <sys/socket.h>
  8. #include <netinet/in.h>
  9. #include <arpa/inet.h>
  10. // 定义websocket协议的一些常量
  11. #define WS_MAGIC "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
  12. #define WS_HEADER_LEN 2
  13. #define WS_MASK_LEN 4
  14. #define WS_FIN_BIT 0x80
  15. #define WS_OPCODE_MASK 0x0f
  16. #define WS_MASK_BIT 0x80
  17. #define WS_PAYLOAD_LEN_MASK 0x7f
  18. // websocket帧类型
  19. enum ws_opcode {
  20. WS_OPCODE_CONTINUATION = 0x0,
  21. WS_OPCODE_TEXT = 0x1,
  22. WS_OPCODE_BINARY = 0x2,
  23. WS_OPCODE_CLOSE = 0x8,
  24. WS_OPCODE_PING = 0x9,
  25. WS_OPCODE_PONG = 0xa
  26. };
  27. // 创建websocket连接并进行握手
  28. int ws_connect(char *address, int port)
  29. {
  30. // 创建TCP套接字
  31. int sockfd = socket(AF_INET, SOCK_STREAM, 0);
  32. if (sockfd == -1) {
  33. perror("socket");
  34. return -1;
  35. }
  36. // 设置套接字选项
  37. int flags = fcntl(sockfd, F_GETFL, 0);
  38. if (flags == -1) {
  39. close(sockfd);
  40. perror("fcntl");
  41. return -1;
  42. }
  43. if (fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) == -1) {
  44. close(sockfd);
  45. perror("fcntl");
  46. return -1;
  47. }
  48. // 构造连接地址
  49. struct sockaddr_in addr;
  50. addr.sin_family = AF_INET;
  51. addr.sin_addr.s_addr = inet_addr(address);
  52. addr.sin_port = htons(port);
  53. // 连接到服务器
  54. int ret = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr));
  55. if (ret == -1 && errno != EINPROGRESS) {
  56. close(sockfd);
  57. perror("connect");
  58. return -1;
  59. }
  60. // 等待连接完成
  61. fd_set write_fds;
  62. FD_ZERO(&write_fds);
  63. FD_SET(sockfd, &write_fds);
  64. ret = select(sockfd + 1, NULL, &write_fds, NULL, NULL);
  65. if (ret == -1) {
  66. close(sockfd);
  67. perror("select");
  68. return -1;
  69. }
  70. // 检查连接是否成功
  71. int error = 0;
  72. socklen_t len = sizeof(error);
  73. if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) == -1 || error != 0) {
  74. close(sockfd);
  75. perror("getsockopt");
  76. return -1;
  77. }
  78. // 发送握手请求
  79. char request[1024];
  80. snprintf(request, sizeof(request), "GET / HTTP/1.1\r\n"
  81. "Upgrade: websocket\r\n"
  82. "Connection: Upgrade\r\n"
  83. "Sec-WebSocket-Version: 13\r\n"
  84. "Host: %s:%d\r\n"
  85. "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
  86. "\r\n",
  87. address, port);
  88. ret = write(sockfd, request, strlen(request));
  89. if (ret == -1) {
  90. close(sockfd);
  91. perror("write");
  92. return -1;
  93. }
  94. // 读取握手响应
  95. char response[1024];
  96. ret = read(sockfd, response, sizeof(response) - 1);
  97. if (ret == -1) {
  98. close(sockfd);
  99. perror("read");
  100. return -1;
  101. }
  102. response[ret] = '\0';
  103. // 解析握手响应
  104. char *p = strstr(response, "\r\n\r\n") + 4;
  105. char buf[1024];
  106. snprintf(buf, sizeof(buf), "%s%s", p, WS_MAGIC);
  107. char sha1[20];
  108. mbedtls_sha1((const unsigned char *)buf, strlen(buf), (unsigned char *)sha1);
  109. char output[sizeof(sha1) * 2 + 1];
  110. for(int i = 0; i < sizeof(sha1); i++) {
  111. sprintf(output + i * 2, "%02x", sha1[i]);
  112. }
  113. // 发送握手响应
  114. char handshake[1024];
  115. snprintf(handshake, sizeof(handshake), "HTTP/1.1 101 Switching Protocols\r\n"
  116. "Upgrade: websocket\r\n"
  117. "Connection: Upgrade\r\n"
  118. "Sec-WebSocket-Accept: %s\r\n"
  119. "\r\n",
  120. output);
  121. ret = write(sockfd, handshake, strlen(handshake));
  122. if (ret == -1) {
  123. close(sockfd);
  124. perror("write");
  125. return -1;
  126. }
  127. return sockfd;
  128. }
  129. // 发送websocket数据帧
  130. int ws_send(int sockfd, enum ws_opcode opcode, char *data, int len)
  131. {
  132. // 构造websocket头部
  133. unsigned char header[14];
  134. memset(header, 0, 14);
  135. header[0] = WS_FIN_BIT | opcode;
  136. if (len < 126) {
  137. header[1] = len | WS_MASK_BIT;
  138. header[2] = 0x01; // 随机生成掩码
  139. header[3] = 0x02; // 随机生成掩码
  140. header[4] = 0x03; // 随机生成掩码
  141. header[5] = 0x04; // 随机生成掩码
  142. } else if (len < 65536) {
  143. header[1] = 0x7e | WS_MASK_BIT;
  144. header[2] = (len >> 8) & 0xff;
  145. header[3] = len & 0xff;
  146. header[4] = 0x01; // 随机生成掩码
  147. header[5] = 0x02; // 随机生成掩码
  148. header[6] = 0x03; // 随机生成掩码
  149. header[7] = 0x04; // 随机生成掩码
  150. } else {
  151. header[1] = 0x7f | WS_MASK_BIT;
  152. header[2] = (len >> 56) & 0xff;
  153. header[3] = (len >> 48) & 0xff;
  154. header[4] = (len >> 40) & 0xff;
  155. header[5] = (len >> 32) & 0xff;
  156. header[6] = (len >> 24) & 0xff;
  157. header[7] = (len >> 16) & 0xff;
  158. header[8] = (len >> 8) & 0xff;
  159. header[9] = len & 0xff;
  160. header[10] = 0x01; // 随机生成掩码
  161. header[11] = 0x02; // 随机生成掩码
  162. header[12] = 0x03; // 随机生成掩码
  163. header[13] = 0x04; // 随机生成掩码
  164. }
  165. // 发送websocket数据帧
  166. int ret = write(sockfd, header, WS_HEADER_LEN + WS_MASK_LEN);
  167. if (ret == -1) {
  168. close(sockfd);
  169. perror("write");
  170. return -1;
  171. }
  172. ret = write(sockfd, data, len);
  173. if (ret == -1) {
  174. close(sockfd);
  175. perror("write");
  176. return -1;
  177. }
  178. return 0;
  179. }
  180. // 接收websocket数据帧
  181. int ws_recv(int sockfd, enum ws_opcode *opcode, char **data, int *len)
  182. {
  183. // 读取websocket头部
  184. unsigned char header[14];
  185. memset(header, 0, 14);
  186. int ret = read(sockfd, header, WS_HEADER_LEN);
  187. if (ret == -1) {
  188. close(sockfd);
  189. perror("read");
  190. return -1;
  191. }
  192. if (ret == 0) {
  193. close(sockfd);
  194. return -1;
  195. }
  196. if (!(header[0] & WS_FIN_BIT)) {
  197. printf("fragmented frame received\n");
  198. return -1;
  199. }
  200. *opcode = header[0] & WS_OPCODE_MASK;
  201. int has_mask = header[1] & WS_MASK_BIT;
  202. *len = header[1] & WS_PAYLOAD_LEN_MASK;
  203. unsigned char mask[4];
  204. if (has_mask) {
  205. ret = read(sockfd, mask, WS_MASK_LEN);
  206. if (ret == -1) {
  207. close(sockfd);
  208. perror("read");
  209. return -1;
  210. }
  211. }
  212. // 读取websocket数据
  213. char *buf = malloc(*len + 1);
  214. memset(buf, 0, *len + 1);
  215. ret = read(sockfd, buf, *len);
  216. if (ret == -1) {
  217. close(sockfd);
  218. perror("read");
  219. free(buf);
  220. return -1;
  221. }
  222. if (ret != *len) {
  223. printf("incomplete frame received\n");
  224. free(buf);
  225. return -1;
  226. }
  227. // 解码websocket数据
  228. if (has_mask) {
  229. for (int i = 0; i < *len; i++) {
  230. buf[i] ^= mask[i % 4];
  231. }
  232. }
  233. *data = buf;
  234. return 0;
  235. }
  236. int main(int argc, char *argv[])
  237. {
  238. if (argc != 2) {
  239. fprintf(stderr, "Usage: %s <port>\n", argv[0]);
  240. exit(EXIT_FAILURE);
  241. }
  242. int port = atoi(argv[1]);
  243. // 监听端口并等待连接
  244. int sockfd = ws_connect("localhost", port);
  245. if (sockfd == -1) {
  246. perror("ws_connect");
  247. exit(EXIT_FAILURE);
  248. }
  249. printf("Connected to server\n");
  250. while (1) {
  251. // 接收websocket数据帧
  252. enum ws_opcode opcode;
  253. char *data = NULL;
  254. int len;
  255. int ret = ws_recv(sockfd, &opcode, &data, &len);
  256. if (ret == -1) {
  257. perror("ws_recv");
  258. exit(EXIT_FAILURE);
  259. }
  260. // 处理websocket数据帧
  261. switch (opcode) {
  262. case WS_OPCODE_TEXT:
  263. printf("Recv text: %s\n", data);
  264. // 发送回应
  265. ws_send(sockfd, WS_OPCODE_TEXT, data, len);
  266. break;
  267. case WS_OPCODE_BINARY:
  268. printf("Recv binary data with length %d\n", len);
  269. // 发送回应
  270. ws_send(sockfd, WS_OPCODE_BINARY, data, len);
  271. break;
  272. case WS_OPCODE_CLOSE:
  273. printf("Recv close frame\n");
  274. // 发送关闭响应并退出循环
  275. ws_send(sockfd, WS_OPCODE_CLOSE, NULL, 0);
  276. goto exit_loop;
  277. default:
  278. printf("Invalid opcode %d\n", opcode);
  279. break;
  280. }
  281. free(data);
  282. }
  283. exit_loop:
  284. close(sockfd);
  285. return EXIT_SUCCESS;
  286. }

该示例代码实现了一个简单的websocket server,它监听指定的端口并等待客户端连接,对于接收到的不同类型的websocket数据帧作出回应。你可以运行该程序,然后在网页中使用JavaScript编写websocket client并与之交互。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/1003965
推荐阅读