c语言环形队列

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define BUFFER_SIZE 256 * 1024
#define PACKET_SIZE 8192
#define HEADER_SIZE 16

typedef struct {
    char **buffer;
    int *length;
    int size;
    int read_idx;
    int write_idx;
    int count;
    pthread_mutex_t lock;
    pthread_cond_t not_full;
    pthread_cond_t not_empty;
} CircularBuffer;

typedef struct {
    CircularBuffer *buffer;
    const char *filename;
} ReaderParams;

typedef struct {
    CircularBuffer *buffer;
    const char *dest_ip;
    int dest_port;
} SenderParams;

void circularBufferInit(CircularBuffer *buffer, int size) {
    buffer->buffer = (char**)malloc(sizeof(char*) * size);
    buffer->length = (int*)malloc(sizeof(int) * size);
    for (int i = 0; i < size; i++) {
        buffer->buffer[i] = (char*)malloc(PACKET_SIZE);
        buffer->length[i] = 0;
    }
    buffer->size = size;
    buffer->read_idx = 0;
    buffer->write_idx = 0;
    buffer->count = 0;
    pthread_mutex_init(&buffer->lock, NULL);
    pthread_cond_init(&buffer->not_full, NULL);
    pthread_cond_init(&buffer->not_empty, NULL);
}

void circularBufferWrite(CircularBuffer *buffer, const void *data, size_t size) {
    pthread_mutex_lock(&buffer->lock);

    while (buffer->count == buffer->size) {
        pthread_cond_wait(&buffer->not_full, &buffer->lock);
    }

    char *packet = buffer->buffer[buffer->write_idx];
    int padding_size = PACKET_SIZE - HEADER_SIZE - size;

    // 添加包头
    memcpy(packet, "Custom Header", HEADER_SIZE);

    // 添加数据
    memcpy(packet + HEADER_SIZE, data, size);

    // 补充0
    memset(packet + HEADER_SIZE + size, 0, padding_size);

    // 记录数据包长度
    buffer->length[buffer->write_idx] = size;

    buffer->write_idx = (buffer->write_idx + 1) % buffer->size;
    buffer->count++;

    pthread_cond_signal(&buffer->not_empty);
    pthread_mutex_unlock(&buffer->lock);
}

void circularBufferRead(CircularBuffer *buffer, void *data, size_t size) {
    pthread_mutex_lock(&buffer->lock);

    while (buffer->count == 0) {
        pthread_cond_wait(&buffer->not_empty, &buffer->lock);
    }

    char *packet = buffer->buffer[buffer->read_idx];
    int packet_size = buffer->length[buffer->read_idx];
    int padding_size = PACKET_SIZE - HEADER_SIZE - packet_size;

    // 读取数据
    memcpy(data, packet + HEADER_SIZE, packet_size);

    // 填补的0不需要被读取,直接跳过

    buffer->read_idx = (buffer->read_idx + 1) % buffer->size;
    buffer->count--;

    pthread_cond_signal(&buffer->not_full);
    pthread_mutex_unlock(&buffer->lock);
}

void circularBufferDestroy(CircularBuffer *buffer) {
    pthread_mutex_destroy(&buffer->lock);
    pthread_cond_destroy(&buffer->not_full);
    pthread_cond_destroy(&buffer->not_empty);

    for (int i = 0; i < buffer->size; i++) {
        free(buffer->buffer[i]);
    }
    free(buffer->buffer);
    free(buffer->length);

    buffer->size = 0;
    buffer->read_idx = 0;
    buffer->write_idx = 0;
    buffer->count = 0;
}

void *readerThread(void *params) {
    ReaderParams *readerParams = (ReaderParams*)params;

    FILE *file = fopen(readerParams->filename, "rb");
    if (file == NULL) {
        perror("Failed to open file");
        return NULL;
    }

    char data[PACKET_SIZE];
    size_t bytesRead = 0;

    while ((bytesRead = fread(data, 1, PACKET_SIZE - HEADER_SIZE, file)) > 0) {
        circularBufferWrite(readerParams->buffer, data, bytesRead);
        usleep(1000);
    }

    fclose(file);

    return NULL;
}

int createUdpSocket(const char *dest_ip, int dest_port) {
    int sock = socket(AF_INET, SOCK_DGRAM, 0);

    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(dest_ip);
    server_addr.sin_port = htons(dest_port);

    if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        perror("Failed to connect to UDP server");
        close(sock);
        return -1;
    }

    return sock;
}

void *senderThread(void *params) {
    SenderParams *senderParams = (SenderParams*)params;

    int sock = createUdpSocket(senderParams->dest_ip, senderParams->dest_port);

    char data[PACKET_SIZE];
    while (1) {
        circularBufferRead(senderParams->buffer, data, PACKET_SIZE - HEADER_SIZE);
        send(sock, data, PACKET_SIZE - HEADER_SIZE, 0);
        usleep(1000);
    }

    close(sock);

    return NULL;
}

int main() {
    CircularBuffer buffer;
    circularBufferInit(&buffer, BUFFER_SIZE);

    ReaderParams readerParams;
    readerParams.buffer = &buffer;
    readerParams.filename = "input.txt";

    SenderParams senderParams;
    senderParams.buffer = &buffer;
    senderParams.dest_ip = "127.0.0.1";  // 目标地址
    senderParams.dest_port = 12345;  // 目标端口

    pthread_t readerThreadId;
    pthread_t senderThreadId;

    pthread_create(&readerThreadId, NULL, readerThread, &readerParams);
    pthread_create(&senderThreadId, NULL, senderThread, &senderParams);

    pthread_join(readerThreadId, NULL);
    pthread_join(senderThreadId, NULL);

    circularBufferDestroy(&buffer);

    return 0;
}

备注

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define BUFFER_SIZE 256 * 1024
#define PACKET_SIZE 8192
#define HEADER_SIZE 16

typedef struct {
    char **buffer;
    int *length;
    int size;
    int read_idx;
    int write_idx;
    int count;
    pthread_mutex_t lock;
    pthread_cond_t not_full;
    pthread_cond_t not_empty;
} CircularBuffer;

typedef struct {
    CircularBuffer *buffer;
    const char *filename;
} ReaderParams;

typedef struct {
    CircularBuffer *buffer;
    const char *dest_ip;
    int dest_port;
} SenderParams;

void circularBufferInit(CircularBuffer *buffer, int size) {
    buffer->buffer = (char**)malloc(sizeof(char*) * size);
    buffer->length = (int*)malloc(sizeof(int) * size);
    for (int i = 0; i < size; i++) {
        buffer->buffer[i] = (char*)malloc(PACKET_SIZE);
        buffer->length[i] = 0;
    }
    buffer->size = size;
    buffer->read_idx = 0;
    buffer->write_idx = 0;
    buffer->count = 0;
    pthread_mutex_init(&buffer->lock, NULL);
    pthread_cond_init(&buffer->not_full, NULL);
    pthread_cond_init(&buffer->not_empty, NULL);
}

void circularBufferWrite(CircularBuffer *writbuffer, const void *data, size_t size) {
    pthread_mutex_lock(&writbuffer->lock);

    while (writbuffer->count == writbuffer->size) {
        pthread_cond_wait(&writbuffer->not_full, &writbuffer->lock);
    }

    char *packet = writbuffer->buffer[writbuffer->write_idx];
    int padding_size = PACKET_SIZE - HEADER_SIZE - size;

    // 添加包头
    memcpy(packet, "Custom Header", HEADER_SIZE);

    // 添加数据
    memcpy(packet + HEADER_SIZE, data, size);

    // 补充0
    memset(packet + HEADER_SIZE + size, 0, padding_size);

    // 记录数据包长度
    writbuffer->length[writbuffer->write_idx] = size;

    writbuffer->write_idx = (writbuffer->write_idx + 1) % writbuffer->size;
    writbuffer->count++;

    pthread_cond_signal(&writbuffer->not_empty);
    pthread_mutex_unlock(&writbuffer->lock);
}

void circularBufferWrite(CircularBuffer *buffer, const void *data, size_t size) {
    pthread_mutex_lock(&buffer->lock);

    while (buffer->count == buffer->size) {
        pthread_cond_wait(&buffer->not_full, &buffer->lock);
    }
    /*
	用于判断环形队列是否已满的逻辑,并在队列已满时进行阻塞等待的操作。
buffer->count表示当前环形队列中已经存储的数据包数量。
buffer->size表示环形队列的最大容量,即可以存储的最大数据包数量。
在以上代码中,通过条件判断 buffer->count == buffer->size 来判断环形队列是否已满。如果队列已满,即存储的数据包数量等于最大容量,进入 while 循环。
	*/
    char *packet = buffer->buffer[buffer->write_idx];/*将环形缓冲区中写入位置(buffer->write_idx)索引所指向的字符指针(buffer->buffer[buffer->write_idx])赋值给 packet。

这行代码假设 buffer->buffer 是一个 char** 类型的指针,指向存储数据的字符指针数组。通过访问 buffer->buffer[buffer->write_idx],可以获得当前待写入的位置在环形缓冲区中指向的字符数组的指针。*/
    int padding_size = PACKET_SIZE - HEADER_SIZE - size;/*运算得出填充大小,大于零表示本包数据不足*/

    // 添加包头
    memcpy(packet, "Custom Header", HEADER_SIZE);

    // 添加数据
    memcpy(packet + HEADER_SIZE, data, size);

    // 补充0
    memset(packet + HEADER_SIZE + size, 0, padding_size);

    // 记录数据包长度
    buffer->length[buffer->write_idx] = size;

    buffer->write_idx = (buffer->write_idx + 1) % buffer->size;
    buffer->count++;

    pthread_cond_signal(&buffer->not_empty);//发送信号通知其他等待中的线程,表示缓冲区不再为空,这可能是用于唤醒一个等待从缓冲区中读取数据的消费者线程。
    pthread_mutex_unlock(&buffer->lock);//解锁缓冲区的互斥锁,表示写入操作已完成,
}

void circularBufferRead(CircularBuffer *buffer, void *data, size_t size) {
    pthread_mutex_lock(&buffer->lock);

    while (buffer->count == 0) {
        pthread_cond_wait(&buffer->not_empty, &buffer->lock);
    }

    char *packet = buffer->buffer[buffer->read_idx];
    int packet_size = buffer->length[buffer->read_idx];
    int padding_size = PACKET_SIZE - HEADER_SIZE - packet_size;

    // 读取数据
    memcpy(data, packet + HEADER_SIZE, packet_size);

    // 填补的0不需要被读取,直接跳过

    buffer->read_idx = (buffer->read_idx + 1) % buffer->size;
    buffer->count--;

    pthread_cond_signal(&buffer->not_full);
    pthread_mutex_unlock(&buffer->lock);
}

void circularBufferDestroy(CircularBuffer *buffer) {
    pthread_mutex_destroy(&buffer->lock);
    pthread_cond_destroy(&buffer->not_full);
    pthread_cond_destroy(&buffer->not_empty);

    for (int i = 0; i < buffer->size; i++) {
        free(buffer->buffer[i]);
    }
    free(buffer->buffer);
    free(buffer->length);

    buffer->size = 0;
    buffer->read_idx = 0;
    buffer->write_idx = 0;
    buffer->count = 0;
}

void *readerThread(void *params) {
    ReaderParams *readerParams = (ReaderParams*)params;

    FILE *file = fopen(readerParams->filename, "rb");
    if (file == NULL) {
        perror("Failed to open file");
        return NULL;
    }

    char data[PACKET_SIZE];
    size_t bytesRead = 0;

    while ((bytesRead = fread(data, 1, PACKET_SIZE - HEADER_SIZE, file)) > 0) {
        circularBufferWrite(readerParams->buffer, data, bytesRead);
        usleep(1000);
    }

    fclose(file);

    return NULL;
}

int createUdpSocket(const char *dest_ip, int dest_port) {
    int sock = socket(AF_INET, SOCK_DGRAM, 0);

    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(dest_ip);
    server_addr.sin_port = htons(dest_port);

    if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        perror("Failed to connect to UDP server");
        close(sock);
        return -1;
    }

    return sock;
}

void *senderThread(void *params) {
    SenderParams *senderParams = (SenderParams*)params;

    int sock = createUdpSocket(senderParams->dest_ip, senderParams->dest_port);

    char data[PACKET_SIZE];
    while (1) {
        circularBufferRead(senderParams->buffer, data, PACKET_SIZE - HEADER_SIZE);
        send(sock, data, PACKET_SIZE - HEADER_SIZE, 0);
        usleep(1000);
    }

    close(sock);

    return NULL;
}

int main() {
    CircularBuffer buffer;
    circularBufferInit(&buffer, BUFFER_SIZE);

    ReaderParams readerParams;
    readerParams.buffer = &buffer;
    readerParams.filename = "input.txt";

    SenderParams senderParams;
    senderParams.buffer = &buffer;
    senderParams.dest_ip = "127.0.0.1";  // 目标地址
    senderParams.dest_port = 12345;  // 目标端口

    pthread_t readerThreadId;
    pthread_t senderThreadId;

    pthread_create(&readerThreadId, NULL, readerThread, &readerParams);
    pthread_create(&senderThreadId, NULL, senderThread, &senderParams);

    pthread_join(readerThreadId, NULL);
    pthread_join(senderThreadId, NULL);

    circularBufferDestroy(&buffer);

    return 0;
}
相关推荐
superman超哥4 分钟前
Rust 闭包的定义与捕获:所有权系统下的函数式编程
开发语言·后端·rust·函数式编程·rust闭包·闭包的定义与捕获
曹牧6 分钟前
Java:Math.abs()‌
java·开发语言·算法
期待のcode12 分钟前
Java的泛型
java·开发语言
沐知全栈开发13 分钟前
PostgreSQL 删除数据库指南
开发语言
!停19 分钟前
c语言动态申请内存
c语言·开发语言·数据结构
AC赳赳老秦19 分钟前
pbootcms模板后台版权如何修改
java·开发语言·spring boot·postgresql·测试用例·pbootcms·建站
代码or搬砖40 分钟前
Collections和Arrays
java·开发语言
吴名氏.1 小时前
电子书《Java程序设计与应用开发(第3版)》
java·开发语言·java程序设计与应用开发
于慨1 小时前
dayjs处理时区问题、前端时区问题
开发语言·前端·javascript
listhi5201 小时前
基于MATLAB的LTE系统仿真实现
开发语言·matlab