要在 C 语言中实现一个纯手写的 WebSocket 客户端,你需要了解 WebSocket 协议的基本流程。下面是一个简单的 C 语言 WebSocket 客户端示例,它使用标准 POSIX 套接字 API 进行网络通信。
示例代码
以下是一个简单的 C 语言 WebSocket 客户端示例,能够连接到 WebSocket 服务器、发送消息并接收响应。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <openssl/sha.h>
#define BUFFER_SIZE 1024
// 用于计算WebSocket握手所需的Sec-WebSocket-Key
void base64_encode(const unsigned char *input, size_t length, char *output) {
static const char *base64_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int i = 0, j = 0;
while (length--) {
output[j++] = base64_table[(input[i] >> 2) & 0x3F];
output[j++] = base64_table[((input[i] & 0x03) << 4) | ((length ? input[i + 1] >> 4 : 0) & 0x0F))];
if (length-- > 0)
output[j++] = base64_table[((input[i + 1] & 0x0F) << 2) | ((length ? input[i + 2] >> 6 : 0) & 0x03)];
else
output[j++] = '=';
if (length-- > -1)
output[j++] = base64_table[input[i + length] & 0x3F];
else
output[j++] = '=';
i++;
}
output[j] = '\0';
}
int main() {
int sockfd;
struct sockaddr_in server_addr;
// 创建套接字
sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockfd < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
// 设置服务器地址结构体
memset(&server_addr, sizeof(server_addr), '\0');
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8080); // 替换为你的WebSocket服务器端口
// 将IPv4地址字符串转换为网络字节序
if (inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr) <= 0) { // 替换为你的WebSocket服务器IP地址
perror("inet_pton");
close(sockfd);
exit(EXIT_FAILURE);
}
// 建立连接
if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("connect");
close(sockfd);
exit(EXIT_FAILURE);
}
// 握手请求头部
const char *key_format = "GET /chat HTTP/1.1\r\n"
"Host: localhost:8080\r\n"
"Upgrade: websocket\r\n"
"Connection: Upgrade\r\n"
"Sec-WebSocket-Key: %s\r\n"
"Sec-WebSocket-Version: 13\r\n\r\n";
char sec_websocket_key[24];
unsigned char key_bytes[16];
for(int i=0; i<16; ++i)
key_bytes[i]=rand()%256;
base64_encode(key_bytes,sizeof(key_bytes),(char *)sec_websocket_key);
char handshake_request[BUFFER_SIZE];
snprintf(handshake_request, sizeof(handshake_request), key_format, sec_websocket_key);
if (send(sockfd, handshake_request, strlen(handshake_request), MSG_NOSIGNAL) == -1){
perror("send handshake request failed");
close(sockfd);
exit(EXIT_FAILURE);
}
printf("Sent Handshake:\n%s", handshake_request);
char response[BUFFER_SIZE];
int bytes_received;
bytes_received = recv(sockfd,response,sizeof(response)-1 , MSG_WAITALL);
response[bytes_received]='\000';
printf("Received Handshake Response:\n%s",response);
char *message_to_send="Hello from C WebSocket Client!";
send(sockfd,message_to_send , strlen(message_to_send),MSG_NOSIGNAL );
memset(response,'\000',sizeof(response));
bytes_received=recv(sockfd,response,sizeof(response)-1 ,MSG_WAITALL);
response[bytes_received]='\000';
printf("Received Message from Server:\n%s",response);
close(sockfd);
return EXIT_SUCCESS;
}
编译和运行
为了编译这个代码,你需要链接 OpenSSL 库(用于 Base64 编码),因此在编译时可以用如下命令:
gcc websocket_client.c -o websocket_client -lssl -lcrypto
然后运行客户端程序:
./websocket_client
注意事项
- OpenSSL:确保你已安装 OpenSSL 开发包。
- 错误处理:在实际应用中,需要更完善的错误处理。
- 加密支持:上述示例未考虑 SSL/TLS。如果需要安全连接,请考虑使用
libssl
或其他库。 - 服务端:此客户端假设已经有一个支持 WebSocket 的服务正在监听本地
8080
,并具有相应的处理逻辑。
以上是使用 C 实现一个基本 WebSocket 客户端的方法。如果有其他问题或需求,欢迎继续提问!
内容由零声教学AI助手提供,问题来源于学员提问