select的整理

【传统的Socket 操作流程】

【Windows 下】

服务器:WSAStartup -> socket -> bind -> listen -> while【accept -> recv -> send】 -> closesocket(all) -> WSAClean

客户端:WSAStartup -> socket -> connect -> send -> recv ->closesocket -> WSAClean

【Linux下】

服务器:socket -> bind -> listen -> while【accept -> recv -> send】 -> close(all)

客户端:socket -> connect -> send / write -> recv / read ->close

看服务器端操作流程,上述中属于阻塞的(服务器的进程或线程必须执行完accpet后,等待接收客户端请求(recv),然后应答客户端请求(send),最后关闭连接。完成后才能继续accept下一个客户端的连接......)


【Select 流程】

服务器:socket -> bind -> listen -> while【select -> doSomething( accept | recv | send | close | others ) 】

使用select 来监视文件描述符fd的变化情况——读(accept也是读的)、写、异常,并根据描述符的就绪情况进行处理;

若监视到有数据可接收时,就接收该fd的数据,

若监视到有客户端请求连接,就accept ;

若监视到可发送数据,就发送;

若监视到有异常的fd,则关闭它......


一切皆文件,在Unix下任何设备、管道、FIFO等都是文件形式,socket也不例外,也属于一个文件,socket句柄也就是一个文件描述符


【函数原型】

int select(int maxfdp,            // 集合中最大值的文件描述符的值 + 1(若最大的文件描述符为10,则此值设为10+1),windows下设为0即可
        fd_set *readfds,          // 查看这些文件描述符是否可读(包括:接收数据、accept、连接正常关闭,无需查看读则为NULL)
        fd_set *writefds,         // 查看这些文件描述符是否可写(包括:发送数据、connect,无需查看写则为NULL)
        fd_set *errorfds,         // 查看这些文件描述符是否异常(包括:有连接失败的套接字,无需查看异常则为NULL)
        struct timeval *timeout   // 超时参数,实参为NULL时为阻塞, 0时非阻塞
        );

返回值:存在可读 or 可写 or 异常,返回大于0的值,超时(没有可读、可写、异常的)返回0,出错返回负数


【fd_set 结构体】
fd_set 结构体在 windows 与 linux 平台的定义是不同的:
Linux
fd_set 结构体是存放文件描述符的集合,是一个整数数组,其中每个整数中的每一位(bit)对应一个描述字。
其可容纳的套接字数量为FD_SETSIZE(默认 FD_SETSIZE = 1024,可修改并重新编译内核)
linux下fd_set 结构体定义如下(只保留关键部分代码):
typedef long int __fd_mask;
#define __NFDBITS	(8 * (int) sizeof (__fd_mask)) // __NFDBITS = 8bit * 4bytes = 32
typedef struct {
    __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS]; // __FD_SETSIZE / __NFDBITS = 32
# define __FDS_BITS(set) ((set)->fds_bits)
} fd_set;

可通过以下4个宏来操作fd_set结构体:
#include <sys/select.h>
#include <sys/time.h>

FD_ZERO(fd_set *fdset);            // 清空集合宏
FD_SET(int fd, fd_set *fdset);     // 添加集合宏
FD_CLR(int fd, fd_set *fdset);     // 删除集合宏
FD_ISSET(int fd, fd_set *fdset);   // 检查集合宏

Windows平台

typedef struct fd_set {  
     u_int fd_count;               // 表示该集合套接字数量。最大为64.
     socket fd_array[FD_SETSIZE];  // 套接字数组
} fd_set;


【timeval 结构体】
timeval结构体代表时间值,共有两个成员,一个是tv_sec,另一个是tv_usec
structure timeval {  
    long tv_sec;    // 秒。  
    long tv_usec;   // 毫秒。  
};


### 使用 Navicat Premium 编写 SELECT 查询语句 #### 创建基本的 SELECT 查询 Navicat Premium 提供了一个强大的查询创建工具,允许用户通过图形界面构建 SQL 查询。对于希望执行简单的数据检索操作而言,可以利用此功能来生成基础的 `SELECT` 语句。 例如,在想要从名为 `movies` 的表中选取所有列的数据时,可以通过以下方式设置: ```sql SELECT * FROM movies; ``` 如果仅需特定几项属性,则可以在 `SELECT` 后面指定这些字段名称[^1]。 #### 添加条件过滤 (WHERE 子句) 为了进一步细化所选记录集,可在 `SELECT` 中加入 `WHERE` 条件表达式。这使得能够基于某些标准筛选出符合条件的结果行。比如要找出发布于某一年的所有电影及其主演名单,就可以这样写: ```sql SELECT title, actor_name FROM movies JOIN actors ON movies.actor_id = actors.id WHERE release_year = '2023'; ``` 这里不仅限定了年份范围,还涉及到了两个不同表格之间的关联匹配。 #### 利用 GUI 工具简化复杂查询构建过程 除了手动输入完整的SQL语法外,Navicat Premium 还提供了可视化的 Query Builder 功能,让用户无需记住复杂的命令格式就能轻松搭建起所需的查询逻辑结构。当面对多层嵌套或是跨多个关系型数据库对象的操作场景下尤为有用[^3]。 #### 自动补全与代码提示支持高效开发体验 在实际编写过程中,得益于内置的智能感知机制,每当键入部分关键词后都会弹出相应的选项列表供选择;同时预设了一系列常用模板可供调用,大大提高了工作效率并减少了人为错误的发生几率[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值