libhv教程07--创建一个简单的TCP客户端

文章目录

c版本

#include "hv/hloop.h"
#include "hv/htime.h"

void on_timer(htimer_t* timer) {
    char str[DATETIME_FMT_BUFLEN] = {0};
    datetime_t dt = datetime_now();
    datetime_fmt(&dt, str);

    printf("> %s\n", str);
    // 获取userdata
    hio_t* io = (hio_t*)hevent_userdata(timer);
    // 发送当前时间字符串
    hio_write(io, str, strlen(str));
}

void on_close(hio_t* io) {
}

void on_recv(hio_t* io, void* buf, int readbytes) {
    printf("< %.*s\n", readbytes, (char*)buf);
}

void on_connect(hio_t* io) {
    // 设置read回调
    hio_setcb_read(io, on_recv);
    // 开始读
    hio_read(io);

	// 添加一个定时器
    htimer_t* timer = htimer_add(hevent_loop(io), on_timer, 1000, INFINITE);
    // 设置userdata
    hevent_set_userdata(timer, io);
}

int main(int argc, char** argv) {
    if (argc < 2) {
        printf("Usage: cmd port\n");
        return -10;
    }
    int port = atoi(argv[1]);

	// 创建事件循环
    hloop_t* loop = hloop_new(0);
    // 创建TCP客户端
    hio_t* io = hloop_create_tcp_client(loop, "127.0.0.1", port, on_connect, on_close);
    if (io == NULL) {
        return -20;
    }
    // 运行事件循环
    hloop_run(loop);
    // 释放事件循环
    hloop_free(&loop);
    return 0;
}

完整TCP/UDP客户端程序可参考examples/nc.cexamples/tcp_client_test.c

c++版本

示例代码见:evpp/TcpClient_test.cpp

#include "hv/TcpClient.h"
#include "hv/htime.h"

using namespace hv;

int main(int argc, char* argv[]) {
    if (argc < 2) {
        printf("Usage: %s port\n", argv[0]);
        return -10;
    }
    int port = atoi(argv[1]);

    TcpClient cli;
    int connfd = cli.createsocket(port);
    if (connfd < 0) {
        return -20;
    }
    printf("client connect to port %d, connfd=%d ...\n", port, connfd);
    cli.onConnection = [](const SocketChannelPtr& channel) {
        std::string peeraddr = channel->peeraddr();
        if (channel->isConnected()) {
            printf("connected to %s! connfd=%d\n", peeraddr.c_str(), channel->fd());
            // send(time) every 3s
            setInterval(3000, [channel](TimerID timerID){
                if (channel->isConnected()) {
                    char str[DATETIME_FMT_BUFLEN] = {0};
                    datetime_t dt = datetime_now();
                    datetime_fmt(&dt, str);
                    channel->write(str);
                } else {
                    killTimer(timerID);
                }
            });
        } else {
            printf("disconnected to %s! connfd=%d\n", peeraddr.c_str(), channel->fd());
        }
    };
    cli.onMessage = [](const SocketChannelPtr& channel, Buffer* buf) {
        printf("< %.*s\n", (int)buf->size(), (char*)buf->data());
    };
    cli.onWriteComplete = [](const SocketChannelPtr& channel, Buffer* buf) {
        printf("> %.*s\n", (int)buf->size(), (char*)buf->data());
    };
    // reconnect: 1,2,4,8,10,10,10...
    reconn_setting_t reconn;
    reconn_setting_init(&reconn);
    reconn.min_delay = 1000;
    reconn.max_delay = 10000;
    reconn.delay_policy = 2;
    cli.setReconnect(&reconn);
    cli.start();

    // press Enter to stop
    while (getchar() != '\n');
    return 0;
}

TcpClient更多实用接口

  • setConnectTimeout:设置连接超时
  • setReconnect:设置重连
  • setUnpack: 设置拆包
  • withTLS:SSL/TLS加密通信
在使用C++的libhv库实现WebSocketService时,也可以通过设置WebSocketService的protocols属性来指定要使用的协议。例如: ```c++ WebSocketService service; service.protocols = {"my-custom-protocol"}; service.onopen = [](WebSocketChannel* channel) { // WebSocket连接建立后的处理逻辑 }; service.onmessage = [](WebSocketChannel* channel, const std::string& msg) { // 接收到WebSocket消息后的处理逻辑 }; service.onclose = [](WebSocketChannel* channel, int code, const std::string& reason) { // WebSocket连接关闭后的处理逻辑 }; ``` 在上面的示例中,WebSocketService的protocols属性被设置为"my-custom-protocol"。当客户端发起WebSocket连接时,客户端会在WebSocket握手请求中添加"Sec-WebSocket-Protocol"头,值为"my-custom-protocol"。服务器可以根据该头来确定客户端要使用的协议。 如果需要使用多个协议,则可以在protocols属性中使用逗号分隔的协议列表,例如: ```c++ WebSocketService service; service.protocols = {"my-custom-protocol-1", "my-custom-protocol-2"}; service.onopen = [](WebSocketChannel* channel) { // WebSocket连接建立后的处理逻辑 }; service.onmessage = [](WebSocketChannel* channel, const std::string& msg) { // 接收到WebSocket消息后的处理逻辑 }; service.onclose = [](WebSocketChannel* channel, int code, const std::string& reason) { // WebSocket连接关闭后的处理逻辑 }; ``` 在上面的示例中,WebSocketService的protocols属性被设置为"my-custom-protocol-1"和"my-custom-protocol-2"。当客户端发起WebSocket连接时,客户端会在WebSocket握手请求中添加"Sec-WebSocket-Protocol"头,值为"my-custom-protocol-1, my-custom-protocol-2"。服务器可以根据该头来确定客户端要使用的协议。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ithewei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值