域名备案网站购买,wordpress autumn默认主页,网站开发深圳公司,教育网站制作企业文章目录 一、socket1、创建socket2、网络通信流程3、accept()函数4、signal()函数5、recv()函数6、connect()函数 二、I/O多路复用1.select模型2.poll模型3.epoll模型 注 一、socket
1、创建socket
int socket(int domain,int type,int protocol);
//返回值#xff1a;一个… 文章目录 一、socket1、创建socket2、网络通信流程3、accept()函数4、signal()函数5、recv()函数6、connect()函数 二、I/O多路复用1.select模型2.poll模型3.epoll模型 注 一、socket
1、创建socket
int socket(int domain,int type,int protocol);
//返回值一个有效的socket,失败时返回-1,errno被设置。(1)domain:
PF_INET IPv4互联网协议族
PF_INET6 IPv6互联网协议族
PF_LOCAL 本地通信的协议族
PF_PACKET 内核底层协议族
PF_IPX IPX Novell协议族(2)type数据传输的类型
2.1 SOCK_STREAM
面向连接的socket:
1)数据不会丢失
2数据顺序不会错乱
3双向通道2.2 SOCK_DGRAM
无连接的socket:
1)数据可能会丢失
2数据顺序可能错乱
3传输的效率更高(3)protocol最终使用的协议
在IPv4中,数据传输方式为SOCK_STREAM的协议只有IPPROTO_TCP,数据传输方式为SOCK_DGRAM的协议只有IPPROTO_UDP,也可填0.2、网络通信流程 3、accept()函数
accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
//是在一个套接口接受的一个连接。用于在服务器端接受客户端连接的系统调用。//参数
sockfd套接字描述符该套接口在listen()后监听连接。
addr可选指针指向一缓冲区其中接收为通讯层所知的连接实体的地址。Addr参数的实际格式由套接口创建时所产生的地址族确定。
addrlen可选指针输入参数配合addr一起使用指向存有addr地址长度的整型数。4、signal()函数
//设置某一信号的对应动作
#includesignal.h
void ( *signal( int signum,void(* handler)(int)) ) (int);
或者typedef void (*sig_t)( int );
sig_t signal(int signum,sig_t handler);//参数
1.signum:指明了所要处理的信号类型它可以取除了SIGKILL和SIGSTOP外的任何一种信号。2.handler:描述了与信号关联的动作它可以取以下三种值
1一个无返回值的函数地址
此函数必须在signal()被调用前申明handler中为这个函数的名字。当接收到一个类型为signum的信号时就执行handler 所指定的函数。这个函数应有如下形式的定义
void func(int sig);
2SIG_IGN
这个符号表示忽略该信号执行了相应的signal()调用后进程会忽略类型为sig的信号。
3SIG_DFL
这个符号表示恢复系统对信号的默认处理。5、recv()函数
int recv(SOCKET s, char FAR*buf, int len, int flags);
//是一个用于从套接字接收数据的函数。
//返回值如果接收到的字节数大于0表示实际复制到缓冲区的数据量。如果返回0表示对方已关闭连接。如果返回SOCKET_ERROR表示出现了错误。1.参数
s套接字的描述符指定接收数据的端点。
buf一个指向缓冲区的指针用于存放接收到的数据。
len缓冲区buf的长度。
flags通常设置为0但可以用于控制函数的行为如使用MSG_PEEK查看数据或使用MSG_OOB处理带外数据。2.函数行为
(1)如果套接字处于阻塞模式recv将一直等待直到有数据可读或发生错误。
(2)如果套接字处于非阻塞模式并且没有数据可读recv将返回SOCKET_ERROR并设置WSAEWOULDBLOCK错误。
(3)在数据接收过程中如果网络出现错误recv将返回SOCKET_ERROR。
(4)如果远程端正常关闭连接对于面向连接的套接字如SOCK_STREAMrecv将立即返回接收0个字节。
(5)如果连接被重置对于面向连接的套接字recv将失败并显示错误WSAECONNRESET。6、connect()函数
#include sys/socket.h
int connect(int sockfd, struct sockaddr * serv_addr, int addrlen);
//用于建立与指定socket的连接。
//返回值成功则返回0, 失败返回-1, 错误原因存于errno 中.参数
sockfd标识一个套接字。
serv_addr套接字s想要连接的主机地址和端口号。
addrlenname缓冲区的长度。二、I/O多路复用
1.select模型 int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* errorfds, struct timeval* timeout);
//select函数用于检测一组socket中是否有事件就绪,它能够监视我们需要监视的文件描述符的变化情况——读写或是异常 。
//返回值准备就绪的描述符数若超时则返回0若出错则返回-1。
1.nfdsselect监视的文件句柄数视进程中打开的文件数而定,一般设为你要监视各文件中的最大文件号加一。
2.readfdsselect监视的可读文件句柄集合。
3.writefds: select监视的可写文件句柄集合。
4.exceptfdsselect监视的异常文件句柄集合。
5.timeout本次select()的超时结束时间。见/usr/sys/select.h可精确至百万分之一秒FD_ZERO(fd_set *fdset)清空fdset与所有文件句柄的联系。
FD_SET(int fd, fd_set *fdset)建立文件句柄fd与fdset的联系。
FD_CLR(int fd, fd_set *fdset)清除文件句柄fd与fdset的联系。
FD_ISSET(int fd, fd_set *fdset)检查fdset联系的文件句柄fd是否可读写当0表示可读写。存在的问题 (1)采用轮询的方式扫描bitmap性能会随着socket数量增多而下降。 (2)每次调用select()需要拷贝bitmap。 (3)bitmap的大小(单个进/线程打开的socket数量)由FD_SETSIZE宏设置默认是1024个可以修改但是效率将降低。
2.poll模型
int poll(struct pollfd fds[], nfds_t nfds, int timeout)
//用于监视多个文件描述符的状态变化。
/*返回值
如果函数调用成功则返回所有事件就绪的文件描述符个数。
如果timeout时间耗尽返回0。
如果函数调用失败返回-1同时错误码会被设置。
*/
struct pollfd {
int fd; /*文件描述符*/
short events; /* 等待的需要测试事件 */
short revents; /* 实际发生了的事件也就是返回结果 */
};1.fds指向一个结构体数组的指针每个数组元素都是一个struct pollfd结构用于指定测试某个给定的fd的条件。struct pollfd包含三个成员fd文件描述符events等待的事件revents实际发生的事件。
2.nfds表示fds数组的长度。
3.timeout表示poll函数的超时时间单位是毫秒ms。如果timeout的取值为-1则poll调用后进行阻塞等待直到被监视的某个文件描述符上的某个事件就绪如果timeout的取值为0则poll调用之后进行非阻塞等待无论被监视的文件描述符上的事件是否就绪poll检测之后都会立即返回如果timeout的取值为特定的时间值则poll调用后在指定的时间内进行阻塞等待如果被监视的文件描述符上一直没有事件就绪则在该时间后poll进行超时返回。存在的问题 (1)poll的数据结构是数组转入内核后转换成了链表。 (2)每调用一次poll拷贝一次结构体数组(select()需要拷贝两次bitmap)。 (3)监视的连接数没有1024的限制。但是使用遍历的方法监视越多效率越低。
3.epoll模型
int epoll_create(int size)
//创建一个epoll的句柄size用来告诉内核这个监听的数目一共有多大。成功时返回epoll文件描述符失败时返回-1。
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
//epoll的事件注册函数它不同与select()是在监听事件时告诉内核要监听什么类型的事件而是在这里先注册要监听的事件类型。第一个参数是epoll_create()的返回值第二个参数表示动作用三个宏来表示EPOLL_CTL_ADD注册新的fd到epfd中EPOLL_CTL_MOD修改已经注册的fd的监听事件EPOLL_CTL_DEL从epfd中删除一个fd第三个参数是需要监听的fd第四个参数是告诉内核需要监听什么事。
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout)
//等待事件的产生类似于select()调用。参数events用来存储内核得到的事件的集合maxevents告知内核events的大小timeout是超时时间。成功时返回有多少文件描述符就绪时间到时返回0出错时返回-1。注
内容来自b站C网络编程从Socket基础到Epoll百度。