select demo

#include <iostream>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/select.h>

#include <pthread.h>

#define BUFFER_LEN 128

void* thread1_fun(void* args)
{
    int fd = *(int*)args;
    char buff[BUFFER_LEN] = {0};
    while(true)
    {
        int res = recv(fd, buff, BUFFER_LEN, 0);
        if(res <= 0)
        {
            close(fd);
            break;
        }

        printf("服务器收到消息:%s", buff);
        printf("消息长度:%d\n", res);

        std::string tmp(buff, buff + res);
        std::string str = "客户端收到消息:";
        str += tmp;

        send(fd, str.c_str(), str.size(), 0);
    }

    return nullptr;
}

int main()
{
    int listen_sock = socket(AF_INET, SOCK_STREAM, 0); //创建listen套接字

    if(listen_sock == -1)
    {
        return-1;
    }

    struct sockaddr_in servaddr;
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(9900);

    if(bind(listen_sock, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1)
    {
        return -2;
    }
#if 0   //非阻塞模式
    int flag = fcntl(listen_sock, F_GETFL, 0);
    flag |= O_NONBLOCK;
    fcntl(listen_sock, F_SETFL, flag); 
#endif

    listen(listen_sock, 10);

    

#if 0
    int clientfd = accept(listen_sock, (struct sockaddr*)&client_addr, &clilen);

    unsigned char buffer[BUFFER_LEN] = {0};
    int recvlen = recv(clientfd, buffer, BUFFER_LEN, 0);
    printf("buffer: %srecvlen: %d\n", buffer, recvlen);
    std::string sendstr(buffer, buffer+recvlen);
    std::string str("收到消息:");
    str += sendstr;
    

    send(clientfd, str.c_str(), str.size(), 0);

    printf("%d\n", clientfd);
#elif 0 
    while(true)
    {
        struct sockaddr_in client_addr;
        socklen_t clilen;
        int clientfd = accept(listen_sock, (struct sockaddr*)&client_addr, &clilen);
        
        pthread_t threadID;
        pthread_create(&threadID, NULL, thread1_fun, &clientfd);
    }

#elif 1

    fd_set rfds, wfds, rset, wset;
    FD_ZERO(&rfds);
    FD_SET(listen_sock, &rfds);
    FD_ZERO(&wfds);

    int maxfd = listen_sock;
    char buffer[BUFFER_LEN] = {0};
    int ret = 0;

    while(true)
    {
        
        rset = rfds;
        wset = wfds;
        int nready = select(maxfd + 1, &rset, &wset, NULL, NULL);

        if(FD_ISSET(listen_sock, &rset))
        {
            printf("listen_sock 可读\n");
            struct sockaddr_in client;
            socklen_t lenght = sizeof(client);

            int clientfd = accept(listen_sock, (struct sockaddr *)(&client), &lenght);

            FD_SET(clientfd, &rfds);

            if (clientfd > maxfd)
            {
                maxfd = clientfd;
            }
        }

        
        int i = listen_sock + 1;
        

        
        for(; i < maxfd+1; i++)
        {
            //读事件
            if(FD_ISSET(i, &rset))
            {
                ret = recv(i, buffer, BUFFER_LEN, 0);

                if(ret == 0)
                {
                    close(i);
                    FD_CLR(i, &rfds);
                }
                else 
                {
                    printf("收到客户端的消息:%s", buffer);

                    FD_SET(i, &wfds);
                    FD_CLR(i, &rfds);
                    
                }

                
            }
            else if(FD_ISSET(i, &wset))
            {
                
                send(i, buffer, ret, 0);
                FD_SET(i, &rfds);
                FD_CLR(i, &wfds);
            }
        }

        
    }


#endif

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值