写一个c语言读二进制文件通过websocket 发包函数
时间: 2023-08-02 22:43:03 浏览: 96
js操作二进制数据方法
以下是一个简单的C语言函数,可以读取二进制文件并将其通过WebSocket发送出去:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <openssl/sha.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/buffer.h>
#define BUF_SIZE 4096
char *base64_encode(const unsigned char *buffer, size_t length) {
BIO *bio, *b64;
BUF_MEM *bufferPtr;
b64 = BIO_new(BIO_f_base64());
bio = BIO_new(BIO_s_mem());
bio = BIO_push(b64, bio);
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
BIO_write(bio, buffer, length);
BIO_flush(bio);
BIO_get_mem_ptr(bio, &bufferPtr);
char *outputBuffer = (char *)calloc(1, bufferPtr->length + 1);
memcpy(outputBuffer, bufferPtr->data, bufferPtr->length);
outputBuffer[bufferPtr->length] = '\0';
BIO_free_all(bio);
return outputBuffer;
}
int send_file(char *filename, char *host, int port, char *path) {
FILE *fp;
char buf[BUF_SIZE];
int sock;
struct sockaddr_in serv_addr;
// 打开文件
fp = fopen(filename, "rb");
if (fp == NULL) {
perror("Error opening file");
return 1;
}
// 创建socket
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
perror("Error creating socket");
return 1;
}
// 设置服务器地址
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(host);
serv_addr.sin_port = htons(port);
// 连接服务器
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1) {
perror("Error connecting to server");
return 1;
}
// 构造WebSocket头部
char *ws_header = "GET %s HTTP/1.1\r\n"
"Host: %s:%d\r\n"
"Upgrade: websocket\r\n"
"Connection: Upgrade\r\n"
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
"Sec-WebSocket-Version: 13\r\n\r\n";
char *request = (char *)calloc(1, strlen(path) + strlen(ws_header) + 20);
sprintf(request, ws_header, path, host, port);
// 发送WebSocket头部
send(sock, request, strlen(request), 0);
// 接收服务器返回的WebSocket头部
char response[BUF_SIZE];
recv(sock, response, BUF_SIZE, 0);
// 读取文件内容并发送
while (1) {
size_t bytes_read = fread(buf, 1, BUF_SIZE, fp);
if (bytes_read == 0) {
break;
}
// 将数据转换为WebSocket帧
unsigned char *frame = (unsigned char *)calloc(1, bytes_read + 10);
frame[0] = 0x82; // FIN + Binary
frame[1] = bytes_read;
memcpy(frame + 2, buf, bytes_read);
// 发送WebSocket帧
send(sock, frame, bytes_read + 2, 0);
free(frame);
}
// 关闭socket和文件
fclose(fp);
close(sock);
return 0;
}
int main(int argc, char *argv[]) {
if (argc != 5) {
printf("Usage: %s filename host port path\n", argv[0]);
return 1;
}
char *filename = argv[1];
char *host = argv[2];
int port = atoi(argv[3]);
char *path = argv[4];
send_file(filename, host, port, path);
return 0;
}
```
该函数使用了WebSocket协议将二进制文件发送给服务器。在函数中,我们首先打开文件,然后创建一个socket并连接到服务器。接下来,我们构造一个WebSocket头部,包含了文件内容的相关信息,并将其发送到服务器。
然后,我们读取文件内容,将其转换为WebSocket帧,并发送到服务器。最后,我们关闭socket和文件。
需要注意的是,该函数使用了OpenSSL库中的base64编码函数,因此需要在编译时链接OpenSSL库。可以使用以下命令编译该程序:
```bash
gcc send_file.c -o send_file -lssl -lcrypto
```
其中,`-lssl`和`-lcrypto`参数表示链接OpenSSL库。
阅读全文