socket实现非阻塞网络通信实现

一、select函数

select() 可以阻塞地同时探测一组支持非阻塞的 I / O 设备是否有事件发生(如可读,可写,出现异常等等),直至某一个设备触发了事件或者超过了指定的等待时间。此时我们可以把需要的数据源通道放到 select 的探测范围内,只要相应的数据源准备好 select 就会返回,这时就能无阻塞地读取到数据。

select()函数原型及介绍如下所示

int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* errorfds, struct timeval* timeout);

二、客户端代码实例  

#include <stdio.h>
#include <stdint.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include "mysocket.h"


char     pdevMsg[]="i am imx6ull\r\n";

static  int sockfd;//socket对象

#define SERVER_PORT 8080              //服务器的端口号
#define SERVER_IP   "192.168.1.105"  //服务器的 IP 地址

#define BUFF_SIZE 4096
char    sock_buff[BUFF_SIZE+1];
uint32_t  num=0;
 
//发送网络线程
static void Send_TO_Server_thread_entry(void *param)
{
    while (1)
    {
        sleep(1);
        if(sockfd>0)
        {
            printf("send data to server...=%d\r\n",num++);
            send(sockfd, pdevMsg, sizeof pdevMsg, 0);
        }
    }
}

static void* SocketManageThread(void* parameter)
{
    int count = 0;
    int no = (int) parameter; /* 获得线程的入口参数 */

    struct sockaddr_in server_addr = {0};
    char buf[512];
   
    int ret;

    /* 打开套接字,得到套接字描述符 */
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (0 > sockfd)
    {
      perror("socket error");
      exit(EXIT_FAILURE);
    }

    /* 调用 connect 连接远端服务器 */
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT); //端口号
    inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr);//IP 地址

    //连接服务器
    while(1)
    {
        ret = connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
        if(sockfd>0)
        {
            //tip
            send(sockfd, pdevMsg, sizeof pdevMsg, 0);
            printf("服务器连接成功...\r\n");
            break;
        }
        sleep(2);
        printf("正在连接服务器...\r\n");
    }

    fd_set  fds;
    int32_t max_fd = 0, res = 0;
    max_fd = sockfd + 1;
    FD_ZERO(&fds);
    while (1)
    {
        /* 将需要监听可读事件的描述符加入列表 */
        FD_SET(sockfd, &fds);
        /* 等待设定的网络描述符有事件发生 */
         printf("wai server data to come...\r\n");
        res = select(max_fd, &fds, NULL, NULL, NULL);//阻塞等待网络数据到来

       /* 查看 sock 描述符上有没有发生可读事件 */
        if (FD_ISSET(sockfd, &fds))
        {
            //网络数据接收
            /* 从 sock 连接中接收最大BUFSZ - 1字节数据 */
            res = recv(sockfd, sock_buff, BUFF_SIZE, 0);
            if(res>0)
            {
                //处理网络数据
                sock_buff[res]="\0";
                printf("%s",sock_buff);
            }
        }

        //pipe管道,发送数据,后续添加...

    }
}

int mysocketInit(void)
{
    int result,result1;
    pthread_t tid,tid1;
    result  = pthread_create(&tid,NULL,SocketManageThread,(void*)4);
    //网络发送线程
    result1 = pthread_create(&tid,NULL,Send_TO_Server_thread_entry,(void*)5);
   
    printf("Create network communication task\r\n");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值