嵌入式里驱动 接口提供之平台接口

该代码实现了一个基于UNIX域套接字的服务器和客户端通信。服务器通过`BSP_ServerInit`初始化,接收来自客户端的数据包,进行分析并响应。客户端通过`BSP_clientInit`初始化,设置超时选项,发送和接收消息。服务器使用`BSP_ServerResponse`处理请求,客户端使用`BSP_ClientSndAndRcvMsg`进行消息发送与接收。
摘要由CSDN通过智能技术生成

1、server端

typedef struct {
    CMD_ID_E   eBspCmdId;
    BSP_UINT32 ulDataLength;
    BSP_UINT32 *pulLargeData;
    SOCK_MSG_BUF dataBuf;
} BSP_SOCKETDATA_S;

BSP_INT32 BSP_ServerResponse(BSP_INT32  lFdServer, BSP_SOCKETDATA_S *pstSockData)
{
    BSP_SOCKETDATA_S  *pstResponseData = pstSockData;
    BSP_UINT32            ulAddrLen = 0;
    BSP_UINT32            ulBytes   = 0;
    struct   sockaddr_un stClientAddr;
    ulAddrLen = sizeof(stClientAddr);
    ulBytes = recvfrom(lFdServer, pstResponseData, sizeof(BSP_SOCKETDATA_S), 0, (struct sockaddr *)&stClientAddr,
                       &ulAddrLen);

    if (ulBytes < 0) {
        printf("%s\n", strerror(errno));
        return -1;
    } else if (ulBytes == 0) {
        printf("client shutdown...\n");
        return -1;
    }

    requestAnalysis(pstResponseData);

    if (sendto(lFdServer, pstResponseData, sizeof(BSP_SOCKETDATA_S), 0, (struct sockaddr *)&stClientAddr, ulAddrLen) < 0) {
        printf("%s\n", strerror(errno));
    }

    return 0;
}

BSP_INT32 BSP_ServerInit(BSP_VOID)
{
    BSP_INT32  lFdServer      = 0;
    BSP_UINT32 ulAddrLen      = 0;
    struct   timeval        stTimeOut;
    struct   sockaddr_un stServerAddr = {
        .sun_family = AF_UNIX, .sun_path = {BSP_ADDR_SERVER}
    };
    ulAddrLen = offsetof(struct sockaddr_un, sun_path) + strlen(stServerAddr.sun_path);
    lFdServer = socket(AF_UNIX, SOCK_DGRAM, 0);

    if (lFdServer < 0) {
        printf("%s\n", strerror(errno));
        return -1;
    }

    unlink(stServerAddr.sun_path);

    if (bind(lFdServer, (struct sockaddr *)&stServerAddr, ulAddrLen) < 0) {
        printf("%s\n", strerror(errno));
        goto __EXIT;
    }

    stTimeOut.tv_sec  = 5;
    stTimeOut.tv_usec = 0;

    if (setsockopt(lFdServer, SOL_SOCKET, SO_SNDTIMEO, &stTimeOut, sizeof(stTimeOut)) < 0) {
        printf("%s\n", strerror(errno));
        goto __EXIT;
    }

    return lFdServer;
__EXIT:
    close(lFdServer);
    return -1;
}

BSP_VOID BSP_SetThreadPriority(BSP_UINT32 policy, BSP_UINT32 pri)
{
    BSP_INT32      priMax = 0;
    pthread_attr_t attr = {0};       // 线程属性
    struct sched_param sched = {0};  // 调度策略
    int rs = 0;
    rs = pthread_attr_init(&attr);
    assert(rs == 0);      // 如果 rs 不等于 0,程序 abort() 退出
    //printf("set SCHED_RR policy\n");

    if (policy <= SCHED_RR) {
        rs = pthread_attr_setschedpolicy(&attr, policy);
        assert(rs == 0);
    }

    priMax = sched_get_priority_max(policy);

    if (pri > priMax) {
        LIB_BSP_LOG(BSP_LOG_LEVEL_ERROR, BSP_LOG_COMMLIB_BASE_2, "pri[%d] is more than max(%d)\n", pri, priMax, 0, 0);

    } else {
        sched.sched_priority = pri; //设置优先级
        pthread_attr_setschedparam(&attr, &sched);
        sched.sched_priority = 0;
        pthread_attr_getschedparam(&attr, &sched);
        LIB_BSP_LOG(BSP_LOG_LEVEL_INFO, BSP_LOG_COMMLIB_BASE_3, "the pri is %d\n", sched.sched_priority, 0, 0, 0);
    }

    rs = pthread_attr_destroy(&attr);
    assert(rs == 0);
}


BSP_VOID *BSP_ServerStart(BSP_VOID *pvCfg)
{
    //THREADCONFIG_S *pstPthreadCfg = (THREADCONFIG_S*)pvCfg;
    BSP_INT32             lFd      = 0;
    BSP_SOCKETDATA_S stClientRequest;
    BSP_SetThreadPriority(SCHED_RR, 98);
    pthread_detach(pthread_self());
    lFd = BSP_ServerInit();

    if (lFd < 0) {
        return NULL;
    }

    while (1) {
        memset(&stClientRequest, 0, sizeof(BSP_SOCKETDATA_S));
        BSP_ServerResponse(lFd, &stClientRequest);
    }

    close(lFd);
    return NULL;
}

 

BSP_INT32 BSP_clientInit(BSP_UINT32 timeOutSec)
{
    BSP_INT32  lFdClient      = 0;
    BSP_UINT32 ulAddrLen      = 0;
    struct   sockaddr_un stClientAddr = {
        .sun_family = AF_UNIX,
    };

    lFdClient = BSP_GetClientFd();

    if (lFdClient > 0) {
        if (BSP_SetSocketOpt(lFdClient, timeOutSec) < 0) {
            libBspPrintfSw("setsockopt Fail, Err:%s\n", strerror(errno));
            goto __EXIT;
        }

        return BSP_SUCCESS;
    }

    lFdClient = socket(AF_UNIX, SOCK_DGRAM, 0);

    if (lFdClient < 0) {
        libBspPrintfSw("socket Fail, Err:%s\n", strerror(errno));
        return BSP_ERROR;
    }

    sprintf(stClientAddr.sun_path, "%s%d", BSP_ADDR_CLIENT, getpid());
    ulAddrLen = offsetof(struct sockaddr_un, sun_path) + strlen(stClientAddr.sun_path);
    unlink(stClientAddr.sun_path);

    if (bind(lFdClient, (struct sockaddr *)&stClientAddr, ulAddrLen) < 0) {
        libBspPrintfSw("bind Fail, Err:%s\n", strerror(errno));
        goto __EXIT;
    }

    if (BSP_SetSocketOpt(lFdClient, timeOutSec) < 0) {
        libBspPrintfSw("setsockopt Fail, Err:%s\n", strerror(errno));
        goto __EXIT;
    }

    g_fdClient = lFdClient;
    return BSP_SUCCESS;
__EXIT:
    close(lFdClient);
    libBspPrintfSw("Init Fail, exit\n");
    g_fdClient = 0;
    return BSP_ERROR;
}


BSP_INT32 BSP_SetSocketOpt(BSP_INT32 socketFd, BSP_UINT32 timeOutSec)
{
    struct  timeval  timeout;
    BSP_INT32 timeOut = 0;
    socklen_t optLen = sizeof(timeOut);

    if (getsockopt(socketFd, SOL_SOCKET, SO_RCVTIMEO, &timeOut, &optLen) < 0) {
        libBspPrintfSw("Get socket opt Faill, Err:%s\n", strerror(errno));
        return BSP_ERROR;
    }

    if (timeOutSec !=  timeOut) {
        timeout.tv_sec  = timeOutSec;
        timeout.tv_usec = 0;

        if (setsockopt(socketFd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0) 
        {
            libBspPrintfSw("setsockopt Fail, Err:%s\n", strerror(errno));
            return BSP_ERROR;
        }

        if (setsockopt(socketFd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) < 0)     
        {
            libBspPrintfSw("setsockopt Fail, Err:%s\n", strerror(errno));
            return BSP_ERROR;
        }
    }
    return BSP_SUCCESS;
}





BSP_INT32 BSP_ClientSndAndRcvMsg(BSP_UINT32 timeOutSec, BSP_SOCKETDATA_S *pstSockData)
{
    BSP_UINT32 timeOut = timeOutSec == 0 ? SOCKET_CLIENT_TIME_OUT_SEC : timeOutSec;

    if (BSP_clientInit(timeOut) != BSP_SUCCESS) {
        libBspPrintfSw("BSP Client Init Fail\n");
        return BSP_ERROR;
    }

    if (pstSockData == NULL) {
        printf("Input para is NULL, please Check\n");
        return BSP_ERROR;
    }

    if (BSP_cMsgSend(pstSockData) != BSP_SUCCESS) {
        libBspPrintfSw("BSP_cMsgSend FAIL\n");
        return BSP_ERROR;
    }

    if (BSP_cMsgRecv(pstSockData, pstSockData->eBspCmdId) !=  BSP_SUCCESS) {
        libBspPrintfSw("BSP_cMsgRecv Fail \n");
        return BSP_ERROR;
    }

    if (g_CmdRunResult == BSP_TRUE) {
        return BSP_SUCCESS;
    } else {
        return BSP_ERROR;
    }
}




 

 

 

 

 

 

 

 

2、client端

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值