libevent2的hello world程序 —— 字符大写服务器

本文详细介绍了如何使用libevent2库将输入的字符转换为大写,并在服务器端进行处理,包括socket操作、事件循环管理、输入输出回调函数的设计等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

采用libevent2将输入的字符变成大写,然后在返回去,代码如下

/* For sockaddr_in */
#include <netinet/in.h>
/* For socket functions */
#include <sys/socket.h>
/* For fcntl */
#include <fcntl.h>

#include <event2/event.h>
#include <event2/buffer.h>
#include <event2/bufferevent.h>

#include <assert.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

#define MAX_LINE 16384
static const int MY_PORT = 40713;
static const int LISTEN_QUENE = 16;

/**
 * 将字符变成大写
 */
char DoUpper(char c)
{
    if ('a' <= c && c <= 'z')
    {
        c = c - ('a' - 'A');
    }
    return c;
}

/**
 * 处理输入数据的回调函数
 */
void ReadCallBack(struct bufferevent *pBuffEnt, void *pContext)
{
    struct evbuffer* pInstream = bufferevent_get_input(pBuffEnt);
    struct evbuffer* pOutstream = bufferevent_get_output(pBuffEnt);

    char *szLine;
    size_t n;
    // 注意,返回的line是在堆上分配的内存,用完后马上需要清理,否则产生内存泄漏
    while ((szLine = evbuffer_readln(pInstream, &n, EVBUFFER_EOL_LF)))
    {
        // 将当前行的字符串转换
        for (int i = 0; i < n; ++i)
        {
            szLine[i] = DoUpper(szLine[i]);
        }

        // 将当前数据输出给客户端
        evbuffer_add(pOutstream, szLine, n);
        evbuffer_add(pOutstream, "\n", 1);
        free(szLine);
    }

    if (evbuffer_get_length(pInstream) >= MAX_LINE) {
        /* Too long; just process what there is and go on so that the buffer
         * doesn't grow infinitely long. */
        char buf[1024];
        while (evbuffer_get_length(pInstream)) {
            int n = evbuffer_remove(pInstream, buf, sizeof(buf));
            for (int i = 0; i < n; ++i)
            {
                buf[i] = DoUpper(buf[i]);
            }
            evbuffer_add(pOutstream, buf, n);
        }
        evbuffer_add(pOutstream, "\n", 1);
    }
}

void ErrorCallBack(struct bufferevent *bev, short error, void *ctx)
{
    if (error & BEV_EVENT_EOF) {
        /* connection has been closed, do any clean up here */
        printf("ErrorCallBack, connection closed\n");
    } else if (error & BEV_EVENT_ERROR) {
        perror("ErrorCallBack");
    } else if (error & BEV_EVENT_TIMEOUT) {
        /* must be a timeout event handle, handle it */
        /* ... */
    }
    bufferevent_free(bev);
}

/**
 * 回调函数会接受三个参数
 * listener 注册的fd
 * event    注册的事件
 * arg      注册时的参数
 */
void DoAccept(evutil_socket_t nListenSock, short event, void *pArg)
{
    // 获取链接的fd
    struct sockaddr_storage oAddr;
    socklen_t nAddrLen = sizeof(oAddr);
    int nConnSock = accept(nListenSock, (struct sockaddr*)&oAddr, &nAddrLen);
    if (nConnSock < 0) {
        perror("accept");
    } else if (nConnSock > FD_SETSIZE) {
        close(nConnSock);
    } else {
        evutil_make_socket_nonblocking(nConnSock); // 设置为非堵塞的socket

        // 获取传入的参数——event base,自对象在DoAccpet中穿件,用于存放所有的fd
        struct event_base *pEventBase = (struct event_base*)pArg;
        // 创建一个缓冲事件,缓冲事件,顾名思义,就是当数据缓冲到一定程度,才触发,而不是只要有数据就触发
        struct bufferevent* pBuffEnt = bufferevent_socket_new(pEventBase, nConnSock, BEV_OPT_CLOSE_ON_FREE);
        bufferevent_setcb(pBuffEnt, ReadCallBack, NULL, ErrorCallBack, NULL);
        // “程度”通过高/低水位来设定
        bufferevent_setwatermark(pBuffEnt, EV_READ, 0, MAX_LINE);
        // 必须调用这句,否则enabled == false
        bufferevent_enable(pBuffEnt, EV_READ|EV_WRITE);
    }
}

void Run(void)
{
    // 设置地址,此服务器监听在40713上
    struct sockaddr_in oAddr;
    oAddr.sin_family = AF_INET;
    oAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    oAddr.sin_port = htons(MY_PORT);

    // 创建监听socket
    evutil_socket_t nListenSock = socket(AF_INET, SOCK_STREAM, 0);
    evutil_make_socket_nonblocking(nListenSock);

    // 将监听socket设置为地址重用
    int nOne = 1;
    setsockopt(nListenSock, SOL_SOCKET, SO_REUSEADDR, &nOne, sizeof(nOne));

    // 绑定端口
    if (bind(nListenSock, (struct sockaddr*)&oAddr, sizeof(oAddr)) < 0)
    {
        perror("bind");
        return;
    }

    // 开始监听
    if (listen(nListenSock, LISTEN_QUENE)<0)
    {
        perror("listen");
        return;
    }

    // 创建事件的集合对象
    struct event_base *pEventBase = event_base_new();
    if (NULL == pEventBase)
    {
        perror("event_base creating failed");
        return; /*XXXerr*/
    }
    // 将listen socket fd的read事件添加到事件集合中
    // EV_PERSIST设置监听socket的读取事件(新的连接)持续发生
    struct event* pListenEvent = event_new(pEventBase, nListenSock, EV_READ|EV_PERSIST, DoAccept, (void*)pEventBase);

    // 注册监听事件
    event_add(pListenEvent, NULL);

    // 开始主程序的循环
    event_base_dispatch(pEventBase);
}

int main(int c, char **v)
{
    // 设置标准输出stdout没有缓冲,直接输出任何异常
    setvbuf(stdout, NULL, _IONBF, 0);

    Run();
    return 0;
}

转载于:https://www.cnblogs.com/bourneli/archive/2012/01/06/2315151.html

内容概要:该论文聚焦于T2WI核磁共振图像超分辨率问题,提出了一种利用T1WI模态作为辅助信息的跨模态解决方案。其主要贡献包括:提出基于高频信息约束的网络框架,通过主干特征提取分支和高频结构先验建模分支结合Transformer模块和注意力机制有效重建高频细节;设计渐进式特征匹配融合框架,采用多阶段相似特征匹配算法提高匹配鲁棒性;引入模型量化技术降低推理资源需求。实验结果表明,该方法不仅提高了超分辨率性能,还保持了图像质量。 适合人群:从事医学图像处理、计算机视觉领域的研究人员和工程师,尤其是对核磁共振图像超分辨率感兴趣的学者和技术开发者。 使用场景及目标:①适用于需要提升T2WI核磁共振图像分辨率的应用场景;②目标是通过跨模态信息融合提高图像质量,解决传统单模态方法难以克服的高频细节丢失问题;③为临床诊断提供更高质量的影像资料,帮助医生更准确地识别病灶。 其他说明:论文不仅提供了详细的网络架构设计与实现代码,还深入探讨了跨模态噪声的本质、高频信息约束的实现方式以及渐进式特征匹配的具体过程。此外,作者还对模型进行了量化处理,使得该方法可以在资源受限环境下高效运行。阅读时应重点关注论文中提到的技术创新点及其背后的原理,理解如何通过跨模态信息融合提升图像重建效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值