Files
ldb/proactor.c
1iaan 0dc86f5aa5 协议定义与实现, 协议支持 批处理、特殊字符如\r\n\0。与单条命令测试。
/**
 * Header: 	| magic(4) | payloadLen(4) |
 *
 * Request
 * Payload: | opcount(4) | repeat Cmd |
 * Cmd: 	| OP(1) | argc(4) | repeat Arg |
 * Arg:		| arglen(4) | arg |
 *
 * Response
 * Payload: | opcount(4) | repeat Rsp |
 * Rsp:		| OP(1) | status(1) | datalen(4) | data |
 */

 kvstore层,先解析,再执行,最后构建返回体。
 一个是半包问题,没有处理。
 另一个是感觉协议结构有点麻烦,
2026-01-05 23:20:37 +08:00

191 lines
4.0 KiB
C
Executable File

#include <stdio.h>
#include <liburing.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#define EVENT_ACCEPT 0
#define EVENT_READ 1
#define EVENT_WRITE 2
extern int kvs_protocol(char *msg, int length, char *response);
struct conn_info {
int fd;
int event;
};
int p_init_server(unsigned short port) {
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in serveraddr;
memset(&serveraddr, 0, sizeof(struct sockaddr_in));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(port);
if (-1 == bind(sockfd, (struct sockaddr*)&serveraddr, sizeof(struct sockaddr))) {
perror("bind");
return -1;
}
listen(sockfd, 10);
return sockfd;
}
#define ENTRIES_LENGTH 1024
#define BUFFER_LENGTH 1024
int set_event_recv(struct io_uring *ring, int sockfd,
void *buf, size_t len, int flags) {
struct io_uring_sqe *sqe = io_uring_get_sqe(ring);
struct conn_info accept_info = {
.fd = sockfd,
.event = EVENT_READ,
};
io_uring_prep_recv(sqe, sockfd, buf, len, flags);
memcpy(&sqe->user_data, &accept_info, sizeof(struct conn_info));
}
int set_event_send(struct io_uring *ring, int sockfd,
void *buf, size_t len, int flags) {
struct io_uring_sqe *sqe = io_uring_get_sqe(ring);
struct conn_info accept_info = {
.fd = sockfd,
.event = EVENT_WRITE,
};
io_uring_prep_send(sqe, sockfd, buf, len, flags);
memcpy(&sqe->user_data, &accept_info, sizeof(struct conn_info));
}
int set_event_accept(struct io_uring *ring, int sockfd, struct sockaddr *addr,
socklen_t *addrlen, int flags) {
struct io_uring_sqe *sqe = io_uring_get_sqe(ring);
struct conn_info accept_info = {
.fd = sockfd,
.event = EVENT_ACCEPT,
};
io_uring_prep_accept(sqe, sockfd, (struct sockaddr*)addr, addrlen, flags);
memcpy(&sqe->user_data, &accept_info, sizeof(struct conn_info));
}
typedef int (*msg_handler)(char *msg, int length, char *response);
static msg_handler kvs_handler;
int proactor_start(unsigned short port, msg_handler handler) {
int sockfd = p_init_server(port);
kvs_handler = handler;
struct io_uring_params params;
memset(&params, 0, sizeof(params));
struct io_uring ring;
io_uring_queue_init_params(ENTRIES_LENGTH, &ring, &params);
#if 0
struct sockaddr_in clientaddr;
socklen_t len = sizeof(clientaddr);
accept(sockfd, (struct sockaddr*)&clientaddr, &len);
#else
struct sockaddr_in clientaddr;
socklen_t len = sizeof(clientaddr);
set_event_accept(&ring, sockfd, (struct sockaddr*)&clientaddr, &len, 0);
#endif
char buffer[BUFFER_LENGTH] = {0};
char response[BUFFER_LENGTH] = {0};
while (1) {
io_uring_submit(&ring);
struct io_uring_cqe *cqe;
io_uring_wait_cqe(&ring, &cqe);
struct io_uring_cqe *cqes[128];
int nready = io_uring_peek_batch_cqe(&ring, cqes, 128); // epoll_wait
int i = 0;
for (i = 0;i < nready;i ++) {
struct io_uring_cqe *entries = cqes[i];
struct conn_info result;
memcpy(&result, &entries->user_data, sizeof(struct conn_info));
if (result.event == EVENT_ACCEPT) {
set_event_accept(&ring, sockfd, (struct sockaddr*)&clientaddr, &len, 0);
//printf("set_event_accept\n"); //
int connfd = entries->res;
set_event_recv(&ring, connfd, buffer, BUFFER_LENGTH, 0);
} else if (result.event == EVENT_READ) { //
int ret = entries->res;
if (ret == 0) {
close(result.fd);
} else if (ret > 0) {
//int kvs_protocol(char *msg, int length, char *response);
ret = kvs_handler(buffer, ret, response);
set_event_send(&ring, result.fd, response, ret, 0);
}
} else if (result.event == EVENT_WRITE) {
//
int ret = entries->res;
//printf("set_event_send ret: %d, %s\n", ret, buffer);
set_event_recv(&ring, result.fd, buffer, BUFFER_LENGTH, 0);
}
}
io_uring_cq_advance(&ring, nready);
}
}