static void tcp_stream_close(tcp_server_stream_t *stream) { tcp_server_t *server = NULL; if (NULL == stream) { return; } server = stream->server; if (stream->pool) { mem_pool_destroy(&stream->pool); } if (stream->sock_fd >= 0) { close(stream->sock_fd); } /* 从busy链表中删除 */ delete_stream_from_busy_list(server, stream); /* 放入到idle链表尾部 */ add_stream_into_idle_list(server, stream); /* reset stream */ stream->sock_fd = -1; stream->pool = NULL; stream->close = 0; stream->error = 0; stream->data = NULL; stream->server = NULL; }
tcp_client_t *tcp_client_create(int max_conn) { tcp_client_t *client = NULL; int max_conn_count = TCP_MAX_STREAM_NUM; int i = 0; client = (tcp_client_t *)malloc(sizeof(tcp_client_t)); if (NULL == client) { goto error; } bzero(client, sizeof(tcp_client_t)); client->rcv_cb = rcv_cb_default; client->snd_cb = snd_cb_default; if (max_conn > 0) { max_conn_count = max_conn; } /* 创建并发连接结构 */ client->streams = (tcp_client_stream_t *)malloc(sizeof(tcp_client_stream_t) * max_conn_count); if (NULL == client->streams) { log_error("malloc for client->streams failed."); goto error; } bzero(client->streams, sizeof(tcp_client_stream_t) * max_conn_count); client->stream_num = max_conn_count; /* idle stream链表初始化 */ for (i = 0; i < max_conn_count; i++) { client->streams[i].index = i; client->streams[i].sock_fd = -1; add_stream_into_idle_list(client, &client->streams[i]); } /* 创建epoll句柄 */ client->epoll_fd = epoll_create(TCP_MAX_CONNECT_NUM); if (client->epoll_fd < 0) { log_error("epoll_create failed, %s", strerror(errno)); goto error; } return client; error: tcp_client_destroy(client); return NULL; }
int tcp_client_add_server(tcp_client_t *client, char *server, int server_port, tcp_client_rcv_cb_t rcv_cb, tcp_client_snd_cb_t snd_cb, tcp_client_conn_cb_t conn_cb) { tcp_client_stream_t *stream = NULL; stream = get_idle_tcp_client_stream(client); if (NULL == stream) { log_error("get idle tpc client stream failed for %s.", server); return 0; } if (!tcp_client_stream_init(client, stream, server_ip, port, rcv_cb, snd_cb, conn_cb)) { log_error("tcp_client_stream_init failed."); add_stream_into_idle_list(client, stream); return 0; } add_stream_into_busy_list(client, stream); return 1; }
tcp_server_t *tcp_server_create(int port, int max_conn) { tcp_server_t *server = NULL; tcp_server_stream_t *stream = NULL; int max_conn_count = TCP_MAX_STREAM_NUM; int i = 0; struct sockaddr_in server_addr; struct epoll_event event; server = (tcp_server_t *)malloc(sizeof(tcp_server_t)); if (NULL == server) { goto error; } bzero(server, sizeof(tcp_server_t)); server->rcv_cb = rcv_cb_default; server->snd_cb = snd_cb_default; server->port = port; if (max_conn > 0) { max_conn_count = max_conn; } /* 创建并发连接结构 */ server->streams = (tcp_server_stream_t *)malloc(sizeof(tcp_server_stream_t) * max_conn_count); if (NULL == server->streams) { log_error("malloc for server->streams failed."); goto error; } bzero(server->streams, sizeof(tcp_server_stream_t) * max_conn_count); server->stream_num = max_conn_count; /* idle stream链表初始化 */ for (i = 0; i < max_conn_count; i++) { server->streams[i].index = i; add_stream_into_idle_list(server, &server->streams[i]); } /* 创建listen socket */ server->listen_fd = socket(AF_INET, SOCK_STREAM, 0); if (-1 == server->listen_fd) { log_error("create socket failed, %s", strerror(errno)); goto error; } /* 设置为非阻塞 */ if (!set_non_blocking(server->listen_fd)){ log_error("set_non_blocking failed."); goto error; } /* 设置地址重用 */ if (!set_reuse_addr(server->listen_fd)) { log_error("set reuse addr failed."); goto error; } /* 绑定端口 */ bzero(&server_addr, sizeof(struct sockaddr_in)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(server->port); if (bind(server->listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { log_error("bind server addr failed, %s", strerror(errno)); goto error; } /* 设置监听 */ if (listen(server->listen_fd, TCP_MAX_LISTEN_NUM) < 0) { log_error("listen failed, %s", strerror(errno)); goto error; } /* 创建epoll句柄 */ server->epoll_fd = epoll_create(TCP_MAX_CONNECT_NUM); if (server->epoll_fd < 0) { log_error("epoll_create failed, %s", strerror(errno)); goto error; } /* 获取空闲的stream */ stream = get_idle_tcp_stream(server); if (NULL == stream) { log_error("get_idle_tcp_stream for listen stream failed."); goto error; } /* 将listen fd加入epoll */ bzero(&event, sizeof(event)); event.data.fd = server->listen_fd; event.data.ptr = stream; event.events = EPOLLIN | EPOLLET; /* 创建listen stream */ tcp_stream_init(server, stream, server->listen_fd, NULL); stream->snd_cb = NULL; stream->rcv_cb = accept_cb; add_stream_into_busy_list(server, stream); return server; error: tcp_server_destroy(server); return NULL; }