Linux网络编程(二)

本文探讨了Linux网络编程中的TCP半关闭状态和TIME_WAIT状态,解释了如何通过shutdown()和setsockopt()进行端口复用。接着介绍了多路I/O转接服务器的三种主要方法:select、poll和epoll,分析了它们的优缺点,并提到了epoll的边沿触发和非阻塞IO特性。此外,还提到了心跳包、线程池等优化策略。
摘要由CSDN通过智能技术生成

1、TCP半关闭状态:主动发起关闭方才会处于的状态,被动方不会

TIME_WAIT:主动发起关闭方会处于的状态2MSL超时:大约一分钟左右:不确定对方是否收到自己的ACK(回应FIN):等满2MSL:确保主动关闭方发送的最后一个ACK到达对方

shutdown();实现半关闭,还可以指定关闭状态:使用close()只是描述符引用计数减1,shutdown全关

TIME_WAIT状态不能再次监听同一个端口

端口复用:setsockopt():使处于TIME_WAIT状态的时,依旧可以监听

int opt=1;

setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));

2、多路I/O转接服务器:不再由应用程序自己监视客户端连接,取而代之由内核代替应用程序监视

主要方法有3种:

1)select

  #include <sys/select.h>
  #include <sys/time.h>
  #include <sys/types.h>
  #include <unistd.h>
int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);

参1:所监听的所有文件描述符中,最大的文件描述符+1

fd_set:文件描述符事件集合(位图)

参2、3、4:所监听的文件描述符可读、可写、异常事件(读用的比较多):!传入传出参数

参5:超时:时间结构体

返回值:成功:返回监听的所有监听集合中,满足条件的总数:读+写+异常

              失败:返回-1,设置errono

 void FD_ZERO(fd_set *set);//将set清空
 void FD_CLR(int fd, fd_set *set);//将fd从set中清楚
 int  FD_ISSET(int fd, fd_set *set);//判断fd是否在集合中
 void FD_SET(int fd, fd_set *set);//将fd加入到set中

缺点:

1、同时监听的文件描述符:文件描述符上限:1024

2、返回的是发生变化的总数,判断是谁比较难 自定义数据结构:数组

3、监听集合和满足监听条件集合是一个,将原有集合保存

2)poll:select升级版

优点:1、突破1024上限 2、监听、返回集合分离 3、搜索范围变小

 #include <poll.h>

 int poll(struct pollfd *fds, nfds_t nfds, int timeout);
struct pollfd {
        int   fd;         /* file descriptor */
        short events;     /* requested events */
        short revents;    /* returned events */
 };

参1:结构体数组首地址

参2:数组里面监听的元素的个数

fd[0].fd=listenfd;

fd[0].events=POLLIN/POLLOUT/POLLERR

fd[0].revents(返回参数)

参2:-1:阻塞等 0:立即返回,不等待 >0等待时间

3)epoll:LINUX下select/poll增强版

 #include <sys/epoll.h>
int epoll_create(int size);

创建一个epoll句柄,参数size用来告诉内核坚挺的文件描述符个数,和系统有关

返回一个文件描述符,指向一个红黑树树根节点

#include <sys/epoll.h>

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

控制某个epoll监控上的文件描述符上的事件:注册、修改、删除

epfd:文件描述符 

opt:EPOLL_CTL_AD EPOLL_CTL_MOD EPOLL_CTL_DEL

fd:对谁操作

event:结构体

 typedef union epoll_data {
               void        *ptr;
               int          fd;
               uint32_t     u32;
               uint64_t     u64;
           } epoll_data_t;

struct epoll_event {
               uint32_t     events;      /* Epoll events */
               epoll_data_t data;        /* User data variable */
           };

events: EPOLLIN/ EPOLLOUT/ EPOLLERR

成功返回0,失败返回-1并设置errono

 #include <sys/epoll.h>

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

等待所监听的文件描述符上有事件的产生,类似于select()的调用

struct epoll_event *events:数组!!!(传出参数):数组每一个元素都是结构体

成功返回有多少个文件描述符就绪,时间到时返回0,出错返回-1

 void* ptr:可以封装函数指针

typedef union epoll_data {
               void        *ptr;
               int          fd;
               uint32_t     u32;
               uint64_t     u64;
           } epoll_data_t;

epoll:边沿触发 ET模式/水平触发 LT模式

epoll非阻塞IO:1、fctl  2、open(对于socket不适用):边沿触发,非阻塞IO效率高

flag=fcntl(connfd,F_GETFL);
flag|=O_NONBLOCK;
fcntl(connfd,F_SETFL,flag);

 3、epoll反应堆(libevent-跨平台、精炼 epoll 回调 核心思想实现)

4、心跳包(乒乓包:加简单数据)协议:应用层 3、设置TCP属性:很少用

5、线程池!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值