select读写

#include <iostream>
using namespace std;

#ifdef WINDOWS_SOCK
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
#define socklen_t int
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#define SOCKET int
#define closesocket(a) close(a)
#endif

#define  SOCK_COUNT 5

SOCKET initSock();

int main()
{

    SOCKET skListen = initSock();

    //select
    int maxfd = skListen;
    int conn_count = 0;
    SOCKET skAll[SOCK_COUNT] = {0};
    char sndbuf[1024];
    sndbuf[0] = ‘\0‘;

    fd_set fdsetr, fdsetw;
    FD_ZERO(&fdsetr);
    FD_ZERO(&fdsetw);
    FD_SET(skListen, &fdsetr);

    fd_set fdRead;
    fd_set fdWrite;

    sockaddr_in acceptAddr;
    socklen_t len = sizeof(acceptAddr);
    //该参数为空时,则为阻塞select了
    struct timeval timeout = {3,0};
    while(true)
    {
        fdRead = fdsetr;
        fdWrite = fdsetw;

        //参考unix网络编程卷1(第三版):第6章,每个参数介绍很详细
        int num = select(maxfd + 1, &fdRead, &fdWrite, 0, &timeout);
        if (num > 0)
        {
            for (int i=0; i<conn_count; i++)
            {
                //recv
                if(FD_ISSET(skAll[i], &fdRead))
                {
                    char buf[1024];
                    int ir = recv(skAll[i], buf, 1024, 0);
                    if (ir == -1)
                    {
                        getpeername(skAll[i], (sockaddr*)&acceptAddr, &len);
                        cout<<"diss conn IP:"<<inet_ntoa(acceptAddr.sin_addr)
                            <<",PORT:"<<ntohs(acceptAddr.sin_port)<<endl;

                        closesocket(skAll[i]);
                        FD_CLR(skAll[i], &fdsetr);
                        skAll[i] = 0;
                        conn_count--;
                    }
                    else if (ir == 0)
                    {
                        cout<<"0:disconnect"<<endl;

                        closesocket(skAll[i]);
                        FD_CLR(skAll[i], &fdsetr);
                        skAll[i] = 0;
                        conn_count--;
                    }
                    else
                    {
                        buf[ir]=‘\0‘;
                        cout<<buf<<endl;

                        //fdwrite
                        char snd[50] = "notify client";
                        memcpy(sndbuf, snd, strlen(snd)+1);
                        FD_SET(skAll[i], &fdsetw);
                    }
                }

                //write
                if (FD_ISSET(skAll[i], &fdWrite))
                {
                    int ilen = strlen(sndbuf);
                    if (ilen > 0)
                    {
                        int ret = send(skAll[i], sndbuf, ilen, 0);
                        if (ret > 0 )
                        {
                            cout<<"send :"<<ret<<endl;
                        }

                        //FD_CLR(skAll[i], &fdsetr);
                        //FD_CLR(skAll[i], &fdsetw);
                        //closesocket(skAll[i]);
                        //conn_count--;
                    }

                    sndbuf[0] = ‘\0‘;
                }
            }//end for

            //accept
            if (FD_ISSET(skListen, &fdRead))
            {
                SOCKET skClient = accept(skListen, (sockaddr*)&acceptAddr, &len);
                cout<<"conn IP:"<<inet_ntoa(acceptAddr.sin_addr)
                <<",PORT:"<<ntohs(acceptAddr.sin_port)<<endl;

                FD_SET(skClient, &fdsetr);
                maxfd = skListen > skClient ? skListen : skClient;

                if (conn_count >= SOCK_COUNT)
                {
                    cout<<"max conn limit"<<endl;
                    closesocket(skClient);
                }
                else
                {

                int tmp = conn_count;
                do
                {
                    if(skAll[tmp] == 0)
                    {
                        skAll[conn_count++] = skClient;
                        break;
                    }
                    tmp++;

                    if (tmp== SOCK_COUNT)
                    {
                        tmp= 0;
                    }
                }while(conn_count != tmp);
                }
            }

        }
    }

    system("pause");
    return 0;
}

SOCKET initSock()
{
#ifdef WINDOWS_SOCK
    //1.init
    WSADATA wsa;
    if (WSAStartup(MAKEWORD(2,2), &wsa))
    {
        cout<<"1"<<endl;
    }
#endif

    //2.socket
    SOCKET skListen = socket(AF_INET, SOCK_STREAM, 0);

    //3.bind
    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8080);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    bind(skListen, (sockaddr*)&addr, sizeof(addr));

    //4.listen
    listen(skListen, 5);

    return skListen;
}
时间: 2024-11-05 18:33:41

select读写的相关文章

对于redis底层框架的理解(五)

之前总结了redis的通讯流程,基本框架,epoll的封装等等,这次介绍下 redis对于select模型的封装 //select 模型 typedef struct aeApiState { //读文件描述符集合,写文件描述符集合 fd_set rfds, wfds; /* We need to have a copy of the fd sets as it's not safe to reuse * FD sets after select(). */ //读写集合的副本 fd_set _

enmo_day_02

Secure CRT, putty, 等终端工具 DML :u, d, i, m 增,删,改,合并 DDL : DCL : DQL : 数据字典 :存放在数据文件中,SYSTEM表空间里,纪录数据的变化. 逻辑数据库结构 表空间tablespace :每个表空间由一个或多个数据库文件组成 段 segment:数据段,索引段,回退段,临时段 区 extent:磁盘空间分配的最小单位,存储于段中,由连续的数据快组成. 数据块block :数据库中最小的数据组织单位与管理单位,其大小有DB_BLOCK

MySQL 日常运维业务账号权限的控制

在MySQL数据库日常运维中,对业务子账号的权限的统一控制十分必要. 业务上基本分为读账号和写账号两种账号,所以可以整理为固定的存储过程,让数据库自动生成对应的库的账号,随机密码.以及统一的读权限,写权限.(这里没有对 host进行过多的限制.只赋给通用的192.168.% .有兴趣的同学可以在存储过程加个参数,对host 控制) delimiter // set session sql_log_bin=OFF; drop PROCEDURE IF EXISTS `usercrt` // CRE

串口读写,select 检测有数据时就接收,防止阻塞问题

Makefile: EXEC = uart_raw OBJS = uart_raw.o SRC = uart_raw.c #CC = arm-none-linux-gnueabi-gcc CC = /home/hongzhunzhun/work/OpenWrt-SDK-sunxi-for-linux-x86_64-gcc-4.8-linaro_uClibc-0.9.33.2/staging_dir/toolchain-arm_cortex-a7+neon_gcc-4.8-linaro_uClib

mysql主从复制与读写分离

MySQL主从复制与读写分离 MySQL主从复制(Master-Slave)与读写分离(MySQL-Proxy)实践 Mysql作为目前世界上使用最广泛的免费数据库,相信所有从事系统运维的工程师都一定接触过.但在实际的生产环境中,由单台Mysql作为独立的数据库是完全不能满足实际需求的,无论是在安全性,高可用性以及高并发等各个方面. 因此,一般来说都是通过 主从复制(Master-Slave)的方式来同步数据,再通过读写分离(MySQL-Proxy)来提升数据库的并发负载能力 这样的方案来进行部

select 函数1

Select在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只是习惯写诸如connect.accept.recv或recvfrom这样的阻塞程序(所谓阻塞方式block,顾名思义,就是进程或是线程执行到这些函数时必须等待某个事件的发生,如果事件没有发生,进程或线程就被阻塞,函数不能立即返回).可是使用Select就可以完成非阻塞(所谓非阻塞方式non-block,就是进程或线程执行此函数时不必非要等待事件的发生,一旦执行肯定返回,以返回值的不

mysql读写分离

mysql读写分离  静态分离:直接将服务器地址写入程序  动态分离:通过代理服务器对数据进行读写操作,由代理服务器判定读写操作,在主服务器上写数据,在          从服务器上读数据.    1.使用mysql-proxy实现读写分离  # ./mysql-proxy --proxy-backend-addresses=10.0.5.150:3306 --proxy-read-only-backend-addresses=10.0.5.151:3306 --proxy-lua-script

多路复用之select、epoll、poll

IO的多路复用:一个进程可以监视多个描述符,一旦某个描述符读就绪或写就绪,能够通知进程程序进行相应的读写操作 使用场景: 1.当客户处理多个描述符(网络套接口)或一个客户同时处理多个套接口 2.TCP服务器既要处理监听套接口又要处理已经连接的套接口 3.一个服务器处理多个服务或多个协议也要使用I/O复用 与多进程和多线程相比,I/O多路复用最大优点系统开销小,系统也不必创建进程或线程,因而也不用维护这些进程和线程 支持I/O多路复用的系统调用:select.poll.epoll本质上都是同步IO

mysql-proxy源码安装及配置mysql读写分离

安装Mysql-proxy关联系统包 libevent libevent-devel glib2 glib2-devel lua 5.1.x lua-devel-5.1.x pkg-config mysql-devel openssl openssl-devel gcc* 2安装MySQL-proxy 0.8.5 下载源码包并解压 在源码包路径下安装 ./configure –prefix=/u01/mysql-proxy make make install 3.配置mysql-proxy.cn