int32_t init_net_handle(struct net_t* net) { net->epoll_handle = -1; /*创建epoll_event缓存*/ net->wait_event = NET_NEW_ARRAY(struct epoll_event, net->cfg.num_wait_event); UT_VERIFY_TRUE(net->wait_event != 0); net->rcv_buf = NET_NEW_ARRAY(char, net->cfg.recv_buf_size); UT_VERIFY_TRUE(net->rcv_buf != 0); /*创建epoll句柄*/ net->epoll_handle = epoll_create(65536); return net->epoll_handle != -1?0:-1; FAIL: if (net->wait_event != 0) { NET_DELETE(net->wait_event); net->wait_event = 0; } if (net->rcv_buf != 0) { NET_DELETE(net->rcv_buf); net->rcv_buf = 0; } return -1; }
struct ut_channel_t* ut_channel_create( int32_t idx, struct ut_net_t* net) { struct ut_channel_t* channel = 0; // 参数有效性检查 UT_VERIFY_TRUE(idx >= 0); UT_VERIFY_TRUE(net != 0); UT_VERIFY_TRUE(net->cfg.st_channel_size >= sizeof(struct ut_channel_t)); channel = (struct ut_channel_t*)ut_new(net->cfg.st_channel_size); UT_VERIFY_TRUE(channel != 0); channel->sock = ut_sock_invalid(); ut_list_init(&channel->queue_inuse, channel); channel->index = idx; channel->net = net; return channel; FAIL: if (channel != 0) { ut_channel_delete(channel); } return 0; }
int32_t ut_net_config_set_connectionlimit(struct ut_net_config_t* cfg, int32_t limit) { UT_VERIFY_TRUE(cfg != 0); UT_VERIFY_TRUE(limit > 0 && limit <= 65536); cfg->num_connection_limit = limit; return 0; FAIL: return -1; }
int32_t ut_net_send(struct ut_channel_t* channel, const char* data, int32_t datalen) { UT_VERIFY_TRUE(channel != 0); UT_VERIFY_TRUE(data != 0); UT_VERIFY_TRUE(datalen > 0); return ut_sock_send(channel->sock, data, datalen); FAIL: return 0; }
void ut_net_config_delete(struct ut_net_config_t* cfg) { UT_VERIFY_TRUE(cfg != 0); UT_DELETE(cfg); FAIL: return; }
int32_t ut_net_channel_index(struct ut_channel_t* channel) { UT_VERIFY_TRUE(channel != 0); return channel->index; FAIL: return -1; }
void ut_net_channel_close(struct ut_channel_t* channel) { UT_VERIFY_TRUE(channel != 0); ut_sock_shutdown(channel->sock); FAIL: return; }
static void do_lost_connection(struct channel_t* channel) { UT_VERIFY_TRUE(0 != channel); UT_VERIFY_TRUE(0 != channel->net); /*通知回调函数,连接断开*/ channel->net->lost_func(channel->net, channel->index, channel->net->net_data, channel->channel_data); /*关闭socket句柄*/ sock_close(channel->sock); channel->sock = -1; /*释放通道资源*/ channel_free(channel->net, channel); /*从epoll中删除*/ epoll_ctl(channel->net->epoll_handle, EPOLL_CTL_DEL, channel->sock, 0); FAIL: return; }
void ut_channel_delete(struct ut_channel_t* channel) { UT_VERIFY_TRUE(channel != 0); ut_channel_finalize(channel); UT_DELETE(channel); FAIL: return; }
int32_t ut_net_channel_getpeer(struct ut_channel_t* channel, int32_t* ip, int32_t* port) { UT_VERIFY_TRUE(channel != 0 && ip != 0 && port != 0); *ip = channel->info.remote_ip; *port = channel->info.remote_port; return 0; FAIL: return -1; }
struct ut_channel_t* ut_net_deliver_socket(struct ut_net_t* net, ut_sock_t sock, recv_data rcvfunc, void* data) { struct ut_channel_t* channel = 0; UT_VERIFY_TRUE(net != 0); UT_VERIFY_TRUE(rcvfunc != 0); UT_CHECK_TRUE(0 == ut_sock_set_keepalive(sock)); UT_CHECK_TRUE(0 == ut_sock_set_nonblock(sock)); // 申请通道资源 channel = ut_channel_malloc(net); UT_CHECK_TRUE(channel != 0); UT_CHECK_TRUE(0 == ut_sock_getsock_info(sock, &channel->info.local_ip, &channel->info.local_port)); UT_CHECK_TRUE(0 == ut_sock_getpeer_info(sock, &channel->info.remote_ip, &channel->info.remote_port)); channel->sock = sock; channel->connection_data = rcvfunc; channel->user_data = data; UT_CHECK_TRUE(0 == do_deliver_socket(net, channel)); net->new_func(channel, net->user_data, channel->user_data); return channel; FAIL: ut_sock_close(sock); if (channel != 0) { channel->sock = ut_sock_invalid(); channel->connection_data = 0; channel->user_data = 0; ut_channel_free(channel); } return 0; }
void ut_channel_free(struct ut_channel_t* channel) { UT_CHECK_TRUE(channel != 0); struct ut_net_t* net = channel->net; UT_VERIFY_TRUE(net != 0); ut_channel_finalize(channel); ut_list_remove(&channel->queue_inuse); ut_list_push_tail(&net->queue_free, &channel->queue_inuse); FAIL: return; }
void ut_channel_finalize(struct ut_channel_t* channel) { UT_VERIFY_TRUE(channel != 0); channel->connection_data = 0; channel->user_data = 0; if (ut_sock_isvalidate(channel->sock)) { ut_sock_close(channel->sock); channel->sock = ut_sock_invalid(); } FAIL: return; }
struct ut_net_config_t* ut_net_config_create() { struct ut_net_config_t* cfg = UT_NEW(struct ut_net_config_t); UT_VERIFY_TRUE(cfg != 0); *cfg = def_cfg; return cfg; FAIL: if (cfg != 0) { UT_DELETE(cfg); } return 0; }
struct ut_net_t* ut_net_create(struct ut_net_config_t* cfg, new_connection newfunc, lost_connection lostfunc, void* data) { struct ut_net_t* net = 0; int32_t i = 0; if (cfg == 0) { cfg = &def_cfg; } UT_VERIFY_TRUE(cfg->st_net_size >= sizeof(struct ut_net_t)); UT_VERIFY_TRUE(cfg->st_channel_size >= sizeof(struct ut_channel_t)); UT_VERIFY_TRUE(cfg->num_connection_limit > 0); UT_VERIFY_TRUE(newfunc != 0); UT_VERIFY_TRUE(lostfunc != 0); net = (struct ut_net_t*)ut_new(cfg->st_net_size); UT_VERIFY_TRUE(net != 0); net->cfg = *cfg; ut_list_init(&net->queue_free, net); ut_list_init(&net->queue_inuse, net); net->new_func = newfunc; net->lost_func = lostfunc; net->user_data = data; for (i = 0; i < cfg->num_connection_limit; i++) { struct ut_channel_t* channel = ut_channel_create(i, net); UT_VERIFY_TRUE(channel != 0); ut_list_push_tail(&net->queue_free, &channel->queue_inuse); } UT_VERIFY_TRUE(0 == init_net_handle(net)); return net; FAIL: ut_net_delete(net); return 0; }
ut_sock_t ut_net_open_listener(const char* ip, int32_t port) { int32_t nerr = 0; ut_sock_t listener = ut_sock_tcp(); if(!ut_sock_isvalidate(listener)) return listener; UT_VERIFY_TRUE(ut_sock_reuseaddr(listener) == 0); nerr = ut_sock_bind(listener, ip, port); UT_CHECK_TRUE(nerr == 0); nerr = ut_sock_set_nonblock(listener); UT_CHECK_TRUE(nerr == 0); nerr = ut_sock_listen(listener, 128); UT_CHECK_TRUE(nerr == 0); return listener; FAIL: ut_net_close_listener(listener); return ut_sock_invalid(); }
void ut_net_delete(struct ut_net_t* net) { ut_list_t* lst = 0; UT_VERIFY_TRUE(0 != net); // 停止工作 while (0 != (lst = ut_list_pop_head(&net->queue_inuse))) { struct ut_channel_t* channel = (struct ut_channel_t*)(lst->value); ut_channel_delete(channel); } while (0 != (lst = ut_list_pop_head(&net->queue_free))) { struct ut_channel_t* channel = (struct ut_channel_t*)(lst->value); ut_channel_delete(channel); } uninit_net_handle(net); // 释放资源 UT_DELETE(net); FAIL: return; }