C语言实现WFQ算法,将这个项目编程三个例程,“发送者”、“接收者”和“路由器”。
时间: 2023-10-06 17:06:46 浏览: 66
好的,下面是一个简单的 C 语言实现 WFQ 算法的示例,包括发送者、接收者和路由器三个例程:
路由器:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_QUEUE_SIZE 1000 //队列最大长度
#define MAX_PACKET_SIZE 1000 //数据包最大长度
//数据包结构体
typedef struct Packet {
int id; //数据包编号
int size; //数据包长度
int weight; //数据包权重
struct Packet *next; //指向下一个数据包的指针
} Packet;
//队列结构体
typedef struct Queue {
Packet *head; //队列头指针
Packet *tail; //队列尾指针
int length; //队列长度
} Queue;
//路由器结构体
typedef struct Router {
Queue *queues; //队列数组
int *weights; //队列权重数组
int num_queues; //队列数量
} Router;
//创建数据包
Packet *create_packet(int id, int size, int weight) {
Packet *packet = (Packet *)malloc(sizeof(Packet));
packet->id = id;
packet->size = size;
packet->weight = weight;
packet->next = NULL;
return packet;
}
//在队列尾部插入数据包
void enqueue(Queue *queue, Packet *packet) {
if (queue->length >= MAX_QUEUE_SIZE) {
printf("Queue is full!\n");
return;
}
if (queue->head == NULL) {
queue->head = packet;
queue->tail = packet;
} else {
queue->tail->next = packet;
queue->tail = packet;
}
queue->length++;
}
//从队列头部删除数据包
Packet *dequeue(Queue *queue) {
if (queue->head == NULL) {
printf("Queue is empty!\n");
return NULL;
}
Packet *packet = queue->head;
queue->head = packet->next;
if (queue->head == NULL) {
queue->tail = NULL;
}
queue->length--;
return packet;
}
//创建路由器
Router *create_router(int num_queues, int *weights) {
Router *router = (Router *)malloc(sizeof(Router));
router->num_queues = num_queues;
router->queues = (Queue *)malloc(sizeof(Queue) * num_queues);
router->weights = (int *)malloc(sizeof(int) * num_queues);
for (int i = 0; i < num_queues; i++) {
router->queues[i].head = NULL;
router->queues[i].tail = NULL;
router->queues[i].length = 0;
router->weights[i] = weights[i];
}
return router;
}
//计算队列中数据包的总权重
int total_weight(Queue *queue) {
int weight = 0;
Packet *p = queue->head;
while (p != NULL) {
weight += p->weight;
p = p->next;
}
return weight;
}
//路由器工作函数
void router_work(Router *router) {
while (1) {
//选择最小的队列并从队列中获取数据包
int min_queue = 0;
int min_weight = total_weight(&(router->queues[0]));
for (int i = 1; i < router->num_queues; i++) {
int weight = total_weight(&(router->queues[i]));
if (weight * router->weights[min_queue] < min_weight * router->weights[i]) {
min_queue = i;
min_weight = weight;
}
}
Packet *packet = dequeue(&(router->queues[min_queue]));
if (packet == NULL) {
continue;
}
//将数据包发送到目标队列
int target_queue = (min_queue + 1) % router->num_queues;
enqueue(&(router->queues[target_queue]), packet);
}
}
int main() {
int num_queues = 2;
int weights[] = {1, 2};
Router *router = create_router(num_queues, weights);
router_work(router);
return 0;
}
```
发送者:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define SERVER_PORT 8888 //服务器端口号
#define MAX_PACKET_SIZE 1000 //数据包最大长度
#define MAX_SEND_INTERVAL 1000000 //最大发送间隔(微秒)
//数据包结构体
typedef struct Packet {
int id; //数据包编号
int size; //数据包长度
int weight; //数据包权重
} Packet;
//发送数据包
void send_packet(int sock_fd, Packet *packet) {
char buf[MAX_PACKET_SIZE];
memcpy(buf, packet, sizeof(Packet));
send(sock_fd, buf, sizeof(Packet), 0);
}
int main() {
int sock_fd;
struct sockaddr_in server_addr;
Packet packet;
int packet_id = 0;
int send_interval = 100000;
srand(time(NULL));
//创建套接字
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if (sock_fd == -1) {
perror("socket");
exit(1);
}
//设置服务器地址
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
server_addr.sin_port = htons(SERVER_PORT);
//连接服务器
if (connect(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
perror("connect");
exit(1);
}
//发送数据包
while (1) {
packet.id = packet_id++;
packet.size = rand() % MAX_PACKET_SIZE + 1;
packet.weight = rand() % 10 + 1;
send_packet(sock_fd, &packet);
usleep(send_interval);
send_interval = send_interval * 2 > MAX_SEND_INTERVAL ? MAX_SEND_INTERVAL : send_interval * 2;
}
//关闭套接字
close(sock_fd);
return 0;
}
```
接收者:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define SERVER_PORT 8888 //服务器端口号
#define MAX_PACKET_SIZE 1000 //数据包最大长度
//数据包结构体
typedef struct Packet {
int id; //数据包编号
int size; //数据包长度
int weight; //数据包权重
} Packet;
//接收数据包
void recv_packet(int sock_fd, Packet *packet) {
char buf[MAX_PACKET_SIZE];
int n = recv(sock_fd, buf, sizeof(Packet), 0);
if (n == -1) {
perror("recv");
exit(1);
}
memcpy(packet, buf, sizeof(Packet));
}
int main() {
int sock_fd, new_sock_fd;
struct sockaddr_in server_addr, client_addr;
int client_addr_len = sizeof(client_addr);
Packet packet;
//创建套接字
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if (sock_fd == -1) {
perror("socket");
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(SERVER_PORT);
//绑定套接字
if (bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
perror("bind");
exit(1);
}
//监听套接字
if (listen(sock_fd, 10) == -1) {
perror("listen");
exit(1);
}
//接收数据包
while (1) {
new_sock_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &client_addr_len);
if (new_sock_fd == -1) {
perror("accept");
exit(1);
}
recv_packet(new_sock_fd, &packet);
printf("Received packet: id=%d size=%d weight=%d\n", packet.id, packet.size, packet.weight);
close(new_sock_fd);
}
//关闭套接字
close(sock_fd);
return 0;
}
```
注意:这只是一个简单的示例,实际使用时需要根据具体情况进行修改和完善。
阅读全文