网络编程(linux下epoll接受或发送消息服务器端)
socket套接口服务器三大步骤
三大步骤
1.创建套接字
2.绑定服务器IP端口
3.开始监听
函数和数据结构详解
int socket(int af,int type,int protocol);
socket函数:
功能描述:
创建socket套接口,用于进行后续的服务器的绑定,监听和服务的开启
参数详情
af int 类型
地址族:
AF_INET(默认值表示IPV4)
AF_INET6(表示IPV6)
AF_UNIX
AF_CAN
AF_RDS
type int类型
传输数据的模式:
SOCK_STREAM:数据流,较为安全的传输数据的方式,一般用于TCP
SOCK_DGRAM:数据报,不安全但是传输快,一般用于UDP
SOCK_RAW
SOCK_PACKET
……
protocol int 类型
协议类型:一般为0,有系统默认制定
IPPROTO_TCP TCP协议
IPPROTO_UDP UDP协议
……
返回值 int类型
返回一个套接口定义,用于后面的操作
sockaddr_in结构体
struct sockaddr_in{
short int sin_family
unsigned short int sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8] //不清楚作用,一般不定义
};
sin_family
地址族:同上
AF_INET(表示IPV4)
AF_INET6(表示IPV6)
……
sin_port
端口号:范围0到65535
尽量不要选取靠前端口号,靠前端口号一般由知名软件占用
sin_addr
地址结构体用于存储服务器IP地址
一般使用
inet_aton(“IP地址”,&object.sin_addr);
进行地址的赋值
注意
申请sockaddr_in变量的时候最好使用memset函数对申请的变量进行初始化
#
int setsockopt(int s,int level,int optname,const char* optval,int optlen);
setsockopt函数
函数功能
对套接口进行一定程度上的设置
参数详情
s int类型
套接口描述符,即socket函数返回值
level int类型
SOL_SOCKET:基本套接口(默认使用这个)
IPPROTO_IP:IPV4套接口
IPPROTO_IPV6:IPV6套接口
IPPROTO_TCP:TCP套接口
optname int 类型
想要设置的选项名
SO_REUSEADDR:允许套接口和一个已在使用中的地址捆绑(TCP协议传输时需要开启此设定)
SO_BROADCAST:允许套接口传送广播信息
SO_DEBUG:记录调试信息
SO_DONTLINER:不要因为数据未发送就阻塞关闭操作。设置本选项相当于将SO_LINGER的l_onoff元素置为零
SO_DONTROUTE:禁止选径
SO_KEEPALⅣE:发送“保持活动”包
SO_OOBINLINE:在常规数据流中接收带外数据
SO_RCVBUF:为接收确定缓冲区大小
SO_SNDBUF:指定发送缓冲区大小
TCP_NODELAY:禁止发送合并的Nagle算法
SO_LINGER 延迟关闭连接
……
optval const char*常量指针类型(不可被修改)
设置功能是否开启
optlen int类型
optval参数的内存长度
返回值 int类型
函数返回的是函数是否正确退出,正常退出返回0,非正常退出返回-1,并且可以通过errno来获得错误代码
EBADF(9):sock不是有效的文件描述词
EFAULT(14):optval指向的内存并非有效的进程空间
EINVAL(22):在调用setsockopt()时,optlen无效
ENOPROTOOPT(92):指定的协议层不能识别选项
ENOTSOCK(88):sock描述的不是套接字
注意
TCP协议传输时需要开启SO_REUSEADDR功能。大致作用应该是客户端断开时,会有一个等待时间,如果没设定此功能,服务器端可能会无法使用该地址
int bind(int sockfd,const struct sockaddr* addr,socklen_t addrlen);
bind函数
函数功能
绑定地址地址端口
参数详情
sockfd int类型
socket函数返回的套接字描述符
addr struct sockaddr*类型
sockaddr_in申请的变量的地址,因为函数中时以前的sockaddr结构体,所以要进行强制转换
addrlen int类型
sockaddr_in申请变量的内存占用长度
返回值 int类型
函数返回的是函数是否正确退出,正常退出返回0(即绑定成功),非正常退出返回-1(即绑定失败)
int listen(int sockfd,int backlog);
listen函数
函数功能
服务器开始监听
参数详解
sockfd int类型
socket函数返回的套接字描述符
backlog int类型
服务器监听客户端的最大个数
返回值
函数返回的是函数是否正确退出,正常退出返回0,非正常退出返回-1
int accept(int sockfd,struct sockaddr* addr,socklen_t* addrlen);
accept函数
函数功能
接受来自客户端连接的请求
参数详解
sockfd int类型
socket函数返回的套接字描述符
addr
客户端的IP地址,如果不是需要可以设置为NULL
addrlen
addr指针指向地址的长度,不需要也可以设置为NULL
返回值
函数返回的是函数是否正确退出,正常退出返回0,非正常退出返回-1
int connect(int sockfd,struct sockaddr* serv_addr,int addrlen);
connect函数
函数功能
请求连接服务器端
参数详解
sockfd int类型
socket函数返回的套接字描述符
serv_addr
服务器端的IP地址
addrlen
serv_addr指针指向地址的长度
返回值
函数返回的是函数是否正确退出,正常退出返回0,非正常退出返回-1
int send(int sockfd,const void* buf,size_t len,int flags);
send函数
函数功能
发送消息到指定电脑
参数详解
sockfd
套接口描述符
buf
要发送数据的缓冲区
len
发送数据的缓冲区buf长度
flags
0:与write()无异
MSG_DONTROUTE:告诉内核,目标主机在本地网络,不用查路由表
MSG_DONTWAIT:将单个I/O操作设置为非阻塞模式
MSG_OOB:指明发送的是带外信息
一般置0
返回值
函数返回的是函数是否正确退出,正常退出返回0,非正常退出返回-1
int recv(int sockfd,void* buf,size_t len,int flags);
recv函数
函数功能
从指定的机子接受消息
参数详解
sockfd
套接口描述符
buf
用于存储接收消息的缓冲区
len
接受消息的缓冲区buf长度
flags
0:常规操作,与read()相同
MSG_OOB:指明发送的是带外信息
MSG_PEEK:可以查看可读的信息,在接收数据后不会将这些数据丢失
一般置0
返回值
函数返回的是函数是否正确退出,正常退出返回0,非正常退出返回-1
epoll函数解析
int epoll_create(int size);
epoll_create函数
函数功能
创建epoll对象句柄
参数详解
size int类型
表示最大能够处理的fd(文件数)(linux系统中对于传输数据的操作是基于文件的)
返回值 int类型
返回的是epoll对象的句柄
注意
由于epoll本身会占用一个fd,所以申请的个数一般为最大监听数+1,并且当不再使用时一定要调用close函数进行关闭
int epoll_ctl(int epfd,int op,int fd,struct epoll_evetnt* event);
epoll_ctl函数
函数功能
epoll的各种事件的操作
参数详解
epfd int类型
epfd即为epoll_create创建的epoll对象句柄,返回值也一样是它
op int类型
EPOLL_CTL_ADD:添加新的fd到epfd中
EPOLL_CTL_MOD:修改已经添加的fd的监听事件
EPOLL_CTL_DEL:从epfd中删除一个fd
fd int类型
通过accpet函数接受来自客户端连接请求生成的文件句柄(文件描述符)
event 监听事件或属性
EPOLLIN :表示对应的文件描述符可以读
EPOLLOUT:表示对应的文件描述符可以写
EPOLLPRI:表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来)
EPOLLERR:表示对应的文件描述符发生错误
EPOLLHUP:表示对应的文件描述符被挂断
EPOLLET: 当epoll处于LT(默认模式)模式时,将epoll设为ET模式
EPOLLONESHOT:只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个socket的话,需要再次把这个socket加入到epoll队列里
注意
LT模式:当epoll_wait函数有事件返回时,应用程序可以不立即处理该事件。下次调用epoll_wait时,会继续执行上次的事件
ET模式:当epoll_wait函数有事件返回时,应用程序必须立即处理该事件。如果不处理,下次调用epoll_wait时,不会处理该事件。ET模式减少了epoll事件重复出发的可能,因此效率要比LT模式高
int epoll_wait(int epfd,struct epoll_event* events,int maxevents,int timeout);
epoll_wait函数
参数详解
epfd int类型
同上,epoll对象句柄
evetns
事件集合,对应某一个对服务器端的请求
maxevents int类型
最大的处理事件的个数,不能大于epoll_create函数所定义的监听最大值size
timeout int类型
超时时间(毫秒),0代表立即返回,-1代表阻塞
返回值
当前需要处理事件的个数