C 利用wss服务端 用例
时间: 2023-07-28 13:10:41 浏览: 105
gsoap客户端Jax-ws服务端实例
以下是一个基于 C 语言的 WebSocket Secure(WSS)服务端的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#define BUFFER_SIZE 1024
int main(int argc, char *argv[]) {
int server_fd, client_fd, opt = 1, len;
struct sockaddr_in server_addr, client_addr;
char buffer[BUFFER_SIZE];
SSL_CTX *ctx;
SSL *ssl;
// 创建 SSL 上下文
SSL_library_init();
ctx = SSL_CTX_new(TLSv1_2_server_method());
if (!ctx) {
printf("SSL_CTX_new() failed: %s\n", strerror(errno));
exit(1);
}
// 加载证书和私钥
if (SSL_CTX_use_certificate_file(ctx, "server.crt", SSL_FILETYPE_PEM) <= 0) {
printf("SSL_CTX_use_certificate_file() failed: %s\n", strerror(errno));
exit(1);
}
if (SSL_CTX_use_PrivateKey_file(ctx, "server.key", SSL_FILETYPE_PEM) <= 0) {
printf("SSL_CTX_use_PrivateKey_file() failed: %s\n", strerror(errno));
exit(1);
}
// 创建 TCP 套接字
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
printf("socket() failed: %s\n", strerror(errno));
exit(1);
}
// 设置 SO_REUSEADDR 选项
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1) {
printf("setsockopt() failed: %s\n", strerror(errno));
exit(1);
}
// 绑定地址和端口
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(8443);
if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
printf("bind() failed: %s\n", strerror(errno));
exit(1);
}
// 开始监听
if (listen(server_fd, 10) == -1) {
printf("listen() failed: %s\n", strerror(errno));
exit(1);
}
printf("Listening on port 8443...\n");
while (1) {
len = sizeof(client_addr);
// 接受客户端连接
if ((client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &len)) == -1) {
printf("accept() failed: %s\n", strerror(errno));
continue;
}
printf("Accepted connection from %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
// 创建 SSL 套接字
ssl = SSL_new(ctx);
SSL_set_fd(ssl, client_fd);
// 进行 SSL 握手
if (SSL_accept(ssl) != 1) {
printf("SSL_accept() failed: %s\n", strerror(errno));
SSL_shutdown(ssl);
close(client_fd);
continue;
}
printf("SSL handshake successful\n");
// 接收数据并回复
while (1) {
len = SSL_read(ssl, buffer, BUFFER_SIZE);
if (len <= 0) {
printf("SSL_read() failed: %s\n", strerror(errno));
break;
}
buffer[len] = '\0';
printf("Received data: %s\n", buffer);
SSL_write(ssl, buffer, strlen(buffer));
}
// 关闭 SSL 套接字
SSL_shutdown(ssl);
SSL_free(ssl);
// 关闭客户端套接字
close(client_fd);
printf("Connection closed\n");
}
// 关闭 SSL 上下文
SSL_CTX_free(ctx);
return 0;
}
```
在上述代码中,我们使用了 OpenSSL 库来实现 WSS。首先,我们创建了一个 SSL 上下文,用于加载证书和私钥,并设置支持的 SSL/TLS 协议版本。然后,我们创建一个 TCP 套接字并绑定地址和端口,开始监听客户端连接。每当有一个客户端连接进来,我们就接受连接并创建一个 SSL 套接字,进行 SSL 握手。一旦握手成功,我们就可以通过 SSL_read() 和 SSL_write() 函数进行数据的收发。当客户端关闭连接时,我们关闭 SSL 套接字并关闭客户端套接字。最后,我们关闭 SSL 上下文并退出程序。
要编译上述代码,你需要安装 OpenSSL 库并使用以下命令:
```
gcc -o wss_server wss_server.c -lssl -lcrypto
```
其中,-lssl 和 -lcrypto 是链接 OpenSSL 库的参数。你还需要准备一个自签名的服务器证书和私钥,用于进行 SSL 握手。你可以使用 OpenSSL 命令生成:
```
openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt -days 365
```
这将生成一个有效期为 365 天的自签名证书和私钥。
阅读全文