乐闻世界logo
搜索文章和话题

如何用 C 实现HTTP Keep Alive和 Websockets 功能代码?

5 个月前提问
4 个月前修改
浏览次数39

2个答案

1
2

HTTP Keep Alive

HTTP Keep Alive 是 HTTP 协议的一个重要特性,它允许在同一 TCP 连接上发送和接收多个 HTTP 请求/响应,而不是每次请求都重新建立连接。这样做可以提高网络通信的效率和性能。

在 C 语言中实现 HTTP Keep Alive,通常需要使用 socket 编程,并在 HTTP 请求头中明确指示 Connection: keep-alive。下面是一个简单的例子,展示如何在 C 语言中使用 socket 实现带有 Keep Alive 功能的 HTTP 客户端。

c
#include <stdio.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> int main() { int sock; struct sockaddr_in server; char message[1000], server_reply[2000]; // 创建 socket sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == -1) { printf("Could not create socket"); } puts("Socket created"); server.sin_addr.s_addr = inet_addr("192.168.0.1"); // 服务器 IP server.sin_family = AF_INET; server.sin_port = htons(80); // HTTP 端口 // 连接到远程服务器 if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0) { perror("Connect failed. Error"); return 1; } puts("Connected\n"); // 发送 HTTP 请求 strcpy(message, "GET / HTTP/1.1\r\nHost: example.com\r\nConnection: keep-alive\r\n\r\n"); if (send(sock, message, strlen(message), 0) < 0) { puts("Send failed"); return 1; } // 接收服务器回复 if (recv(sock, server_reply, 2000, 0) < 0) { puts("recv failed"); return 1; } puts("Server reply :"); puts(server_reply); // 保持连接,按需进行后续通信... close(sock); return 0; }

Websockets

Websockets 提供了在客户端和服务器之间进行全双工通信的能力。在 C 语言中,实现 Websockets 涉及到使用正确的 Websockets 握手,然后在同一连接上进行数据帧的发送和接收。

实现 Websockets 的完整代码比较复杂,但基本步骤包括:

  1. 创建 TCP Socket 连接
  2. 发送 Websocket 握手请求(包括正确的 UpgradeConnection 请求头)。
  3. 解析响应,确保服务器接受了 Websocket 升级。
  4. 发送和接收 Websocket 数据帧

给出一个简化的代码示例,主要展示如何发送 Websocket 握手请求:

c
#include <stdio.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #include <stdlib.h> int main() { int sock; struct sockaddr_in server; char message[1024], server_reply[2000]; // 创建 socket sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == -1) { printf("Could not create socket\n"); return 1; } printf("Socket created\n"); server.sin_addr.s_addr = inet_addr("192.168.0.1"); server.sin_family = AF_INET; server.sin_port = htons(80); // Connect to remote server if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0) { perror("Connect failed. Error"); return 1; } printf("Connected\n"); // Send Websocket upgrade request strcpy(message, "GET /chat HTTP/1.1\r\n"); strcat(message, "Host: example.com\r\n"); strcat(message, "Upgrade: websocket\r\n"); strcat(message, "Connection: Upgrade\r\n"); strcat(message, "Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n"); strcat(message, "Sec-WebSocket-Version: 13\r\n\r\n"); if (send(sock, message, strlen(message), 0) < 0) { puts("Send failed"); return 1; } // Receive a reply from the server if (recv(sock, server_reply, 2000, 0) < 0) { puts("recv failed"); return 1; } puts("Server reply :"); puts(server_reply); // Close the socket close(sock); return 0; }

这两个示例提供了在 C 语言中实现 HTTP Keep Alive 和 Websockets 功能的基本框架。在开发完整的应用时,还需要考虑错误处理、更复杂的数据交换和安全性等问题。

2024年6月29日 12:07 回复

HTTP Keep Alive 在 C 中的实现

HTTP Keep Alive 是一种机制,允许同一个TCP连接上发送和接收多个HTTP请求/响应,而不是每次请求都重新建立连接。在 C 语言中实现这一机制,通常需要在HTTP响应中设置 Connection: keep-alive 头部,并在服务器端保持连接开启状态,直到客户端关闭连接或服务器决定关闭连接。

c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #define PORT 8080 #define BUFFER_SIZE 1024 int main() { int server_fd, new_socket; struct sockaddr_in address; int opt = 1; int addrlen = sizeof(address); char buffer[BUFFER_SIZE] = {0}; char *http_response = "HTTP/1.1 200 OK\nContent-Type: text/plain\nConnection: keep-alive\n\nHello, world!"; // 创建 socket 文件描述符 if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); exit(EXIT_FAILURE); } // 附加 socket 到端口8080 if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { perror("setsockopt"); exit(EXIT_FAILURE); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0) { perror("bind failed"); exit(EXIT_FAILURE); } if (listen(server_fd, 3) < 0) { perror("listen"); exit(EXIT_FAILURE); } while(1) { if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0) { perror("accept"); exit(EXIT_FAILURE); } read(new_socket, buffer, BUFFER_SIZE); printf("%s\n", buffer); send(new_socket, http_response, strlen(http_response), 0); // 注意:为了保持连接,我们不会在这里关闭 new_socket } return 0; }

在 C 中实现 Websockets

Websockets 提供了在单个长连接上进行全双工通信的能力,通常用于网页和服务器之间的实时数据交换。在 C 语言中实现 Websockets 涉及到更多的复杂性,例如需要处理握手协议和帧控制。

c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define PORT 8080 void error(const char *msg) { perror(msg); exit(1); } int main(int argc, char *argv[]) { int sockfd, newsockfd; socklen_t clilen; char buffer[1024]; struct sockaddr_in serv_addr, cli_addr; int n; sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) error("ERROR opening socket"); bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(PORT); if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) error("ERROR on binding"); listen(sockfd, 5); clilen = sizeof(cli_addr); newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); if (newsockfd < 0) error("ERROR on accept"); bzero(buffer,1024); n = read(newsockfd, buffer, 1023); if (n < 0) error("ERROR reading from socket"); printf("Here is the message: %s\n", buffer); n = write(newsockfd, "I got your message", 18); if (n < 0) error("ERROR writing to socket"); close(newsockfd); close(sockfd); return 0; }

这个示例代码展示了如何创建一个 WebSocket 服务器的框架,但需要额外的代码来处理 WebSocket 的握手和数据帧,这通常涉及到更多的细节,如解析 HTTP 请求头,生成与解析特定的控制帧等。对于完整的 WebSocket 服务器实现,您可能需要使用专门的库,如 libwebsocket。

2024年6月29日 12:07 回复

你的答案