TCP 服务端与客户端
介绍如何使用 libcc 的 TCP API:创建监听事件、accept 新连接、处理读写、以及发起主动连接。
TCP 服务端
服务端示例tests/event.c,简化版。
*** 示例代码(tests/event.c)***
#include <libcc.h>
#include <stdio.h>
static bool_t echo_handler(_cc_async_event_t *async, _cc_event_t *e, const uint32_t which) {
if (which & _CC_EVENT_ACCEPT_) {
/* 监听端 accept 会在线程中由 async->accept 执行(见 tests 中完整实现) */
return true;
}
if (which & _CC_EVENT_READABLE_) {
/* 读取并回显 */
char buf[1024];
int32_t r = _cc_recv(e->fd, (byte_t*)buf, sizeof(buf));
if (r <= 0) return false;
_cc_send(e->fd, (byte_t*)buf, r);
return true;
}
if (which & _CC_EVENT_CLOSED_) {
return false;
}
return true;
}
int main(void) {
struct sockaddr_in sa;
_cc_async_event_t async;
_cc_event_t *e;
_cc_install_socket();
if (!_cc_register_poller(&async)) return -1;
e = _cc_event_alloc(&async, _CC_EVENT_ACCEPT_);
e->callback = echo_handler;
e->timeout = 60000;
_cc_inet_ipv4_addr(&sa, nullptr, 8081);
if (!_cc_tcp_listen(&async, e, (_cc_sockaddr_t*)&sa, sizeof(struct sockaddr_in))) {
_cc_free_event(&async, e);
return -1;
}
while (1) {
async.wait(&async, 100);
}
async.free(&async);
return 0;
}
TCP 客户端
客户端示例(调用 _cc_tcp_connect,参考 tests/test_tcp_client.c
客户端使用 _cc_event_alloc 创建带有 _CC_EVENT_CONNECT_ 标志的事件,然后调用 _cc_tcp_connect 发起连接,并在回调中处理可读/可写事件。
#include <libcc.h>
#include <stdio.h>
static bool_t echo_handler(_cc_async_event_t *async, _cc_event_t *e, const uint32_t which) {
if (which & _CC_EVENT_CONNECT_) {
return true;
}
if (which & _CC_EVENT_READABLE_) {
/* 读取并回显 */
char buf[1024];
int32_t r = _cc_recv(e->fd, (byte_t*)buf, sizeof(buf));
if (r <= 0) return false;
_cc_send(e->fd, (byte_t*)buf, r);
return true;
}
if (which & _CC_EVENT_CLOSED_) {
return false;
}
return true;
}
int main(void) {
struct sockaddr_in sa;
_cc_async_event_t async;
_cc_event_t *e;
_cc_install_socket();
if (!_cc_register_poller(&async)) return -1;
e = _cc_event_alloc(async, _CC_EVENT_CONNECT_|_CC_EVENT_TIMEOUT_|_CC_EVENT_READABLE_);
e->callback = echo_handler;
e->timeout = 60000;
_cc_inet_ipv4_addr(&sa, nullptr, 8081);
if (!_cc_tcp_connect(async, event, (_cc_sockaddr_t *)&sa, sizeof(struct sockaddr_in))) {
_cc_free_event(async, event);
return false;
}
while (1) {
async.wait(&async, 100);
}
async.free(&async);
return 0;
}