feat: 初始化 OmniSocket 目录结构与底层网络接口
This commit is contained in:
123
src/core/network.c
Normal file
123
src/core/network.c
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* network.c
|
||||
* 协议分发与工厂模式实现
|
||||
*/
|
||||
|
||||
#include "network.h"
|
||||
#include "common.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* TCP / UDP / KCP 在各自的实现文件中提供以下符号 */
|
||||
extern const struct ProtoVTable TCP_PROTO_VTABLE;
|
||||
extern const struct ProtoVTable UDP_PROTO_VTABLE;
|
||||
extern const struct ProtoVTable KCP_PROTO_VTABLE;
|
||||
|
||||
struct OmniContext {
|
||||
OmniProtocol proto;
|
||||
OmniRole role;
|
||||
const struct ProtoVTable *vt;
|
||||
void *impl; /* 由具体协议实现使用的内部指针 */
|
||||
};
|
||||
|
||||
/* 工厂:根据协议类型选择对应实现 */
|
||||
static const struct ProtoVTable *select_vtable(OmniProtocol proto)
|
||||
{
|
||||
switch (proto) {
|
||||
case OMNI_PROTO_TCP:
|
||||
return &TCP_PROTO_VTABLE;
|
||||
case OMNI_PROTO_UDP:
|
||||
return &UDP_PROTO_VTABLE;
|
||||
case OMNI_PROTO_KCP:
|
||||
return &KCP_PROTO_VTABLE;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
OmniContext *omni_init(OmniRole role,
|
||||
OmniProtocol proto,
|
||||
const char *bind_ip,
|
||||
uint16_t bind_port,
|
||||
const char *peer_ip,
|
||||
uint16_t peer_port)
|
||||
{
|
||||
logger_init();
|
||||
|
||||
const struct ProtoVTable *vt = select_vtable(proto);
|
||||
if (!vt || !vt->init) {
|
||||
logger_log("ERROR", "network", "select_vtable_failed proto=%d",
|
||||
(int)proto);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
OmniContext *ctx = (OmniContext *)calloc(1, sizeof(OmniContext));
|
||||
if (!ctx) {
|
||||
logger_log("ERROR", "network", "calloc_OmniContext_failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->proto = proto;
|
||||
ctx->role = role;
|
||||
ctx->vt = vt;
|
||||
|
||||
OmniContext *impl_ctx = vt->init(role, bind_ip, bind_port, peer_ip, peer_port);
|
||||
if (!impl_ctx) {
|
||||
logger_log("ERROR", "network", "proto_init_failed proto=%d", (int)proto);
|
||||
free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 简化:直接让 impl 指针等于协议实现返回的上下文 */
|
||||
ctx->impl = impl_ctx;
|
||||
|
||||
logger_log("INFO", "network",
|
||||
"omni_init_success proto=%d role=%d bind_port=%u peer_port=%u",
|
||||
(int)proto, (int)role,
|
||||
(unsigned)bind_port,
|
||||
(unsigned)peer_port);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
ssize_t omni_send(OmniContext *ctx, const void *buf, size_t len)
|
||||
{
|
||||
if (!ctx || !ctx->vt || !ctx->vt->send) {
|
||||
return OMNI_ERR_PARAM;
|
||||
}
|
||||
|
||||
ssize_t n = ctx->vt->send((OmniContext *)ctx->impl, buf, len);
|
||||
if (n > 0) {
|
||||
logger_on_send((size_t)n);
|
||||
}
|
||||
logger_log("DEBUG", "network", "omni_send proto=%d bytes=%zd",
|
||||
(int)ctx->proto, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
ssize_t omni_recv(OmniContext *ctx, void *buf, size_t len)
|
||||
{
|
||||
if (!ctx || !ctx->vt || !ctx->vt->recv) {
|
||||
return OMNI_ERR_PARAM;
|
||||
}
|
||||
|
||||
ssize_t n = ctx->vt->recv((OmniContext *)ctx->impl, buf, len);
|
||||
if (n > 0) {
|
||||
logger_on_recv((size_t)n);
|
||||
}
|
||||
logger_log("DEBUG", "network", "omni_recv proto=%d bytes=%zd",
|
||||
(int)ctx->proto, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
void omni_close(OmniContext *ctx)
|
||||
{
|
||||
if (!ctx) return;
|
||||
if (ctx->vt && ctx->vt->close && ctx->impl) {
|
||||
ctx->vt->close((OmniContext *)ctx->impl);
|
||||
}
|
||||
logger_print_performance_log("final");
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user