当前位置: 首页 > wzjs >正文

免费建设一个网站廊坊网站建设外包

免费建设一个网站,廊坊网站建设外包,网站建设欲网站维护,房管网查询中心端口复用 由于有一个MSL,所以上一秒关闭的服务器,可能之前的端口还未释放;又或者是程序突然退出系统没有释放端口,导致端口被占用。 当有新的服务想要用这个端口的时候,会出现错误:服务会出现Bind error:A…

端口复用

由于有一个MSL,所以上一秒关闭的服务器,可能之前的端口还未释放;又或者是程序突然退出系统没有释放端口,导致端口被占用。
当有新的服务想要用这个端口的时候,会出现错误:服务会出现Bind error:Address already in use

解决办法

设置套接字属性,
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);

  • 功能:设置套接字的属性(不仅仅能设置端口复用)
  • 参数
    • sockfd:要操作的文件描述符
    • level:级别,SOL_SOCKET (端口复用的级别)
    • optname:选项的名称,使用SO_REUSEADDR(解决在TimeWait的情况)或SO_REUSEPORT(允许多个线程、进程绑在同一个端口上)
    • optval:端口复用的值(整形) ,1表示可复用,0表示不可复用
    • optlen:optval参数的大小

netstat -参数名

a:所有的socket
p:显示正在使用socket的程序名称
n:直接使用IP地址,不通过域名服务器

I\O多路复用(IO多路转接

BIO模型

遇到read/recv/accept的时候,需要阻塞等待,直到有数据或者连接的时候才能继续往下执行
要么是单任务的时候,一个时刻只能处理一个操作,效率低;
要么是多任务的时候,虽然是多进程、多线程,一个线程或者进程对应一个任务, 但在进程线程之间的切换会消耗CPU资源。
这些的根本问题都是阻塞在那。

select

大概思想是:将要监听的文件的文件描述符表放到一个列表里面,需要监听的就置为1 ,然后把这个交给内核,由内核对这些文件描述符进行检测(我们不需要知道他是怎么检测的,反正他就是知道了)。最后内核返回有变动的文件描述符的数量,和文件描述符列表。我们再从这之中遍历。去读取

#include <sys/time.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <sys/select.h> int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);nfds:委托内核检测的最大文件描述符的值 + 1+1是因为遍历是下标从0开始,for循环<设定)readfds:要检测的文件描述符的读的集合,委托内核检测哪些文件描述符的读的属性一般检测读操作对应的是对方发送过来的数据,因为读是被动的接收数据,检测的就是读缓冲区是一个传入传出参数writefds:要检测的文件描述符的写的集合,委托内核检测哪些文件描述符的写的属性委托内核检测写缓冲区是不是还可以写数据(不满的就可以写)exceptfds:检测发生异常的文件描述符的集合,一般不用timeout:设置的超时时间,含义见select参数列表说明NULL:永久阻塞,直到检测到了文件描述符有变化tv_sec = tv_usec = 0 不阻塞tv_sec > 0,tv_usec > 0:阻塞对应的时间* 返回值* -1:失败* \>0(n):检测的集合中有n个文件描述符发生了变化// 将参数文件描述符fd对应的标志位设置为0 
void FD_CLR(int fd, fd_set *set); 
// 判断fd对应的标志位是0还是1, 返回值 : fd对应的标志位的值,0,返回0, 1,返回1 
int FD_ISSET(int fd, fd_set *set); 
// 将参数文件描述符fd 对应的标志位,设置为1 
void FD_SET(int fd, fd_set *set);
// fd_set一共有1024 bit, 全部初始化为0 
void FD_ZERO(fd_set *set);

在这里插入图片描述
在这里插入图片描述
注意事项:因为内核返回去会改变这个文件包描述符列表,所以最好:
select中需要的监听集合需要两个:

  • 一个是用户态真正需要监听的集合rSet
  • 一个是内核态返回给用户态的修改集合tmpSet

会存在的问题

  • 每次都需要利用FD_ISSET轮训[0, maxfd]之间的连接状态,如果位于中间的某一个客户端断开了连接,此时不应该再去利用FD_ISSET轮训,造成资源浪费
  • 如果在处理客户端数据时,某一次read没有对数据读完,那么造成重新进行下一次时select,获取上一次未处理完的文件描述符,从0开始遍历到maxfd,对上一次的进行再一次操作,效率十分低下

解决:

  • 考虑到select只有1024个最大可监听数量,可以申请等量客户端数组
    • 初始置为-1,当有状态改变时,置为相应文件描述符
    • 此时再用FD_ISSET轮训时,跳过标记为-1的客户端,加快遍历速度
  • 对于问题二:对读缓存区循环读,直到返回EAGAIN再处理数据

select缺点:

  • 每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大
  • 同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大
  • select支持的文件描述符数量太小了,默认是1024
  • fds集合不能重用,每次都需要重置

poll

解决了上面缺点的三四条

epoll

  • 直接在内核态创建 eventpoll实例(结构体),通过epoll提供的API操作该实例 (解决了总是在内核态和用户态拷贝转化内的资源浪费)
  • 结构体中有红黑树双链表,分别用来存储需要检测的文件描述符和**存储已经发生改变的文件描述符
#include <sys/epoll.h>// 创建一个新的epoll实例
// 在内核中创建了一个数据,这个数据中有两个比较重要的数据,一个是需要检测的文件描述符的信息(红黑树),还有一个是就绪列表,存放检测到数据发送改变的文件描述符信息(双向链表)
int epoll_create(int size);// 对epoll实例进行管理:添加文件描述符信息,删除信息,修改信息
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
struct epoll_event { uint32_t events; /* Epoll events */ epoll_data_t data; /* User data variable */ 
};
typedef union epoll_data { void *ptr; int fd; uint32_t u32; uint64_t u64; 
} epoll_data_t;// 检测函数
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

int epoll_create(int size);

  • 功能:创建一个新的epoll实例
  • 参数:size,目前没有意义了(之前底层实现是哈希表,现在是红黑树),随便写一个数,必须大于0
  • 返回值
    • -1:失败
    • >0:操作epoll实例的文件描述符 epfd

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

  • 功能:对epoll实例进行管理:添加文件描述符信息,删除信息,修改信息
  • 参数:
    • epfd:epoll实例对应的文件描述符
    • op:要进行什么操作
      • 添加:EPOLL_CTL_ADD
      • 删除:EPOLL_CTL_DEL
      • 修改:EPOLL_CTL_MOD
    • fd:要检测的文件描述符
    • event:检测文件描述符什么事情,通过设置epoll_event.events,常见操作
      • 读事件:EPOLLIN
      • 写事件:EPOLLOUT
      • 错误事件:EPOLLERR
      • 设置边沿触发:EPOLLET(默认水平触发)
  • 返回值:成功0,失败-1

  • int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

    • 功能:检测哪些文件描述符发生了改变
    • 参数:
      • epfd:epoll实例对应的文件描述符
      • events:传出参数,这个结构体保存了发生了变化的文件描述符的信息
      • maxevents:第二个参数结构体数组的大小
      • timeout:阻塞时长
        • 0:不阻塞
        • -1:阻塞,当检测到需要检测的文件描述符有变化,解除阻塞
        • >0:具体的阻塞时长(ms)
    • 返回值:
      • > 0:成功,返回发送变化的文件描述符的个数
      • -1:失败

实现代码

里面的events是一个结构体,用于存放文件描述符的信息,看可以重用。
如果有多个监听文件例如读和写分开监听,那就分开设置。这里就设置了监听读

服务端:
#include <stdio.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/epoll.h>#define SERVERIP "127.0.0.1"
#define PORT 6789int main()
{// 1. 创建socket(用于监听的套接字)int listenfd = socket(AF_INET, SOCK_STREAM, 0);if (listenfd == -1) {perror("socket");exit(-1);}// 2. 绑定struct sockaddr_in server_addr;server_addr.sin_family = PF_INET;// 点分十进制转换为网络字节序inet_pton(AF_INET, SERVERIP, &server_addr.sin_addr.s_addr);// 服务端也可以绑定0.0.0.0即任意地址// server_addr.sin_addr.s_addr = INADDR_ANY;server_addr.sin_port = htons(PORT);int ret = bind(listenfd, (struct sockaddr*)&server_addr, sizeof(server_addr));if (ret == -1) {perror("bind");exit(-1);}// 3. 监听ret = listen(listenfd, 8);if (ret == -1) {perror("listen");exit(-1);}// 创建epoll实例int epfd = epoll_create(100); //随便写一个大于0的就行// 将监听文件描述符加入实例struct epoll_event event;event.events = EPOLLIN;event.data.fd = listenfd;ret = epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &event);if (ret == -1) {perror("epoll_ctl");exit(-1);}// 此结构体用来保存内核态返回给用户态发生改变的文件描述符信息struct epoll_event events[1024]; //这里设置1024个结构体,那么就是最多同时连接1024个,具体个数可以自己再调整// 不断循环等待客户端连接while (1) {// 使用epoll,设置为永久阻塞,有文件描述符变化才返回int num = epoll_wait(epfd, events, 1024, -1);if (num == -1) {perror("poll");exit(-1);} else if (num == 0) {// 当前无文件描述符有变化,执行下一次遍历// 在本次设置中无效(因为select被设置为永久阻塞)continue;} else {// 遍历发生改变的文件描述符集合for (int i = 0; i < num; i++) {// 判断监听文件描述符是否发生改变(即是否有客户端连接)int curfd = events[i].data.fd;if (curfd == listenfd) {// 4. 接收客户端连接struct sockaddr_in client_addr;socklen_t client_addr_len = sizeof(client_addr);int connfd = accept(listenfd, (struct sockaddr*)&client_addr, &client_addr_len);if (connfd == -1) {perror("accept");exit(-1);}// 输出客户端信息,IP组成至少16个字符(包含结束符)char client_ip[16] = {0};inet_ntop(AF_INET, &client_addr.sin_addr.s_addr, client_ip, sizeof(client_ip));unsigned short client_port = ntohs(client_addr.sin_port);printf("ip:%s, port:%d\n", client_ip, client_port);// 将信息加入监听集合event.events = EPOLLIN;event.data.fd = connfd;epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &event);} else {// 只检测读事件if (events[i].events & EPOLLOUT) {continue;}// 接收消息char recv_buf[1024] = {0};ret = read(curfd, recv_buf, sizeof(recv_buf));if (ret == -1) {perror("read");exit(-1);} else if (ret > 0) {printf("recv server data : %s\n", recv_buf);write(curfd, recv_buf, strlen(recv_buf));} else {// 表示客户端断开连接printf("client closed...\n");close(curfd);epoll_ctl(epfd, EPOLL_CTL_DEL, curfd, NULL);break;}}}}}close(listenfd);close(epfd);return 0;
}

EPOLL的LT方式和ET方式

  • LT(缺省模式)
    • 用户不读数据,数据一直在缓冲区,epoll 会一直通知
    • 用户只读了一部分数据,epoll会通知
    • 缓冲区的数据读完了,不通知
  • ET
    • 用户不读数据,数据一致在缓冲区中,epoll下次检测的时候就不通知了
    • 用户只读了一部分数据,epoll不通知
    • 缓冲区的数据读完了,不通知

ET的设计方式:event.events = EPOLLIN | EPOLLET;


文章转载自:

http://0O4Virnk.mwgrf.cn
http://9g5WKbxj.mwgrf.cn
http://yrXYDHvc.mwgrf.cn
http://flGTvDOZ.mwgrf.cn
http://luYlCph2.mwgrf.cn
http://Z0G3iNou.mwgrf.cn
http://augWKhd0.mwgrf.cn
http://1dke4LiX.mwgrf.cn
http://VROzJH81.mwgrf.cn
http://HM0ALmGO.mwgrf.cn
http://zk7dUAlu.mwgrf.cn
http://nN7e8Yxs.mwgrf.cn
http://FjfEXhjG.mwgrf.cn
http://Zg3NcpRa.mwgrf.cn
http://RKjxspWG.mwgrf.cn
http://GrlUhOfa.mwgrf.cn
http://MZLU1FOt.mwgrf.cn
http://BjOp9igD.mwgrf.cn
http://G3qeJ31B.mwgrf.cn
http://iyGo9DAn.mwgrf.cn
http://5Je2sCSI.mwgrf.cn
http://fmFjIMbC.mwgrf.cn
http://fQzfZvKf.mwgrf.cn
http://t3M7fwws.mwgrf.cn
http://uWmH62Wu.mwgrf.cn
http://weSV7eVt.mwgrf.cn
http://EXBdQIK0.mwgrf.cn
http://P8268ilQ.mwgrf.cn
http://exG2nsuo.mwgrf.cn
http://nurwnIRg.mwgrf.cn
http://www.dtcms.com/wzjs/648490.html

相关文章:

  • 查询数据的网站怎么做在建设部网站首页
  • 阿里云大学 网站建设男直接做的视频网站
  • 中国建设银行属于什么类型网站软件开发税率是13%还是6
  • 网站入股云建站石家庄网站制作设计
  • wordpress端口映射wordpress编辑优化
  • 建设厅科技中心网站首页买个网站域名多少钱
  • 网站建设工作计划免费的wordpress主题好
  • 创建自己的网站怎么弄优良的定制网站建设制作商
  • 国内简洁网站设计设计师共享平台
  • 网页制作好了如果让别人搜到揭阳百度快照优化排名
  • 不是网站开发语言的是境外电商有哪些平台
  • 网站怎么关闭网站开发保密协议范本下载
  • 免费网站建设入门登封网站建设
  • 跨境电商数据分析网站房地产建设网站的意义
  • 网站建设励志文章电子商务网站开发基础
  • 一流的网站建设与优化网站建设安全架构
  • 网站关键词seo排名天津建设厅 注册中心网站
  • 盘锦网站变建设怎么注册个人邮箱账号
  • 网站推广方法素材建设一个网站需要哪些费用
  • 金融投资风险公司网站源码手机网站栏目结构图
  • 网站宣传的优点成都网站建设哪家公司好
  • 淘宝网站经营与建设论文网站后台免费模板下载
  • 徐州h5建站模板上海公司注册多久可以拍牌
  • 如何规划一个网站网站开发asp
  • 网站建站网站多少钱达州seo
  • 遵义做网站的网络公司漳州网站建设哪家最权威
  • 游戏开发与网站开发哪个难apicloud怎么样
  • 晋江网站有什么职业做海口仿站定制模板建站
  • 手表价格网站wordpress管理员用户名更改
  • 陕西建设教育网站WordPress防js注入