socket套接字编程
1.协议
1.1 udp协议:用户数据报协议
特性:无连接,不可靠,面向数据报
应用场景:实时性要求大于安全性要求的场景。
1.2 tcp协议:传输控制协议
特性:面向连接,可靠传输,面向字节流
应用场景:安全性要求大于实时性要求的场景。
1.3 在网络通信程序中,通信两端被分为:客户端、服务端。
- 客户端:通常是指编写程序中主动发起请求,提供给客户的通信端。
- 服务端:通常是被动接受请求,提供服务的通信端。
客户端是主动发送请求的一端,也意味着客户端必须提前能够知道服务端的地址信息(ip+port)。服务端的地址信息通常是固定的,并且是提前提供给客户端的。
2.udp通信程序的编写与接口
2.1 server:
2.1.1 创建套接字:在内核中创建一个socket结构体
int socket(int domain, int type,int porotocol);
domain:地址域类型——AF_INET:IPV4通信,使用IPV4 的地址结构
type:套接字类型:SOCK_STREAM ; SOCK_DGRAM
porotocol:本次协议类型:IPPROTO_TCP:6;IPPROTO_UDP:17
TCP必须使用SOCK_STREAM;UDP必须使用SOCK_DGRAM。
2.1.2 为套接字绑定地址信息:在创建套接字创建的socket结构体中加入IP+port信息。
- 告诉操作系统主机收到的哪些数据应接收交给当前的这个socket。
- 确定发送数据到源端地址信息。
int bind(int sockfd,struct sockaddr *addr,socklen_t addrlen);
sockfd:创建套接字返回的操作句柄。
addr:当前绑定的地址信息。
addrlen:地址信息长度。
返回值:成功返回0;失败返回-1。
2.1.3 接收数据:当前进程从指定的socket接收缓冲区中取出数据。
ssize_t recvfrom(int sockfd,void *buf,size_t len,int flag,struct sockaddr *srcaddr,socklen_t *addrlen);
sockfd:操作句柄;
buf:空间地址,用于存放接收的数据;
len:要接收的地址长度;
flag:选项标志,默认为0,表示接收阻塞;
srcaddr:本条数据的源端;
addrlen:输入输出参数——指定要接收多长的地址结构,并且返回实际接收的地址数据长度。
返回值:成功返回实际接收到的数据长度;失败返回-1。
2.1.4 发送数据:将要发送的数据放到socket发送缓冲区中,内核选择合适的时候封装发送。
ssize_t sendto(int sockfd,void *data,int len,int flag,struct sockaddr *peeraddr,socklen_t *addrlen);
sockfd:操作句柄;
data:要发送的数据的空间首地址;
len:要发送的数据长度;
flag:选项标志,默认为0,表示接收阻塞;
srcaddr:对端地址信息;
addrlen:地址结构长度。
返回值:成功返回实际发送到的数据长度;失败返回-1。
2.1.5 关闭套接字
int close(int fd);
2.2 client:
2.2.1 创建套接字:在内核中创建一个socket结构体
2.2.2 为套接字绑定地址信息:大部分情况下忽略这一步,在发送数据时,若socket没有绑定地址时,系统会选择合适的地址进行绑定。
2.2.3 发送数据
2.2.4 接收数据
2.2.5 关闭套接字
3.tcp通信程序的编写与接口
3.1 server:
3.1.1 创建套接字
int socket(int domain,int type,int protocol);
3.1.2 为套接字绑定地址信息
int bind(int sockfd,struct sockaddr *addr,socklen_t len);
3.1.3 开始监听
告诉系统可以开始处理客户端的连接请求,系统会为每一个新的客户端创建一个新的套接字。
int listen(int sockfd,int backlog);
sockfd:描述符
backlog:服务端能够在同一时间处理的最大连接数
已完成连接队列的节点数量=backlog+1
3.1.4 获取新建连接
获取新建套接字的描述符。
int accept(int sockfd,struct sockaddr *cliaddr,socklen_t *addrlen);
sockfd:监听套接字-服务端最早创建的套接字,只用于获取新建连接。
cliaddr:新的连接的客户端地址信息。
addrlen:输入输出参数,指定地址信息长度,以及返回实际长度。
返回值:新建连接的描述符-往后与客户端的通信都通过这个描述符完成。
3.1.5 收发数据
使用的是新建的套接字。
ssize_t send(int sockfd,void *data,int len,int flag);
sockfd:描述符
data:要发送的数据
len:数据长度
flag:0(默认为0,表示接受阻塞)
返回值:成功返回实际发送的数据长度;失败返回-1,连接端开触发异常。
ssize_t recv(int sockfd,void *buf,int len,int flag);
sockfd:描述符
buf:空间地址
len:要接收到数据长度
flag:0
返回值:成功返回实际接收的数据长度;出错返回-1;连接断开返回0。
3.1.6 关闭套接字
int close(fd);
3.2 client:
3.2.1 创建套接字
3.2.2 为套接字绑定地址信息(不推荐主动绑定)
3.2.3 向服务端发送连接请求
int connect(int sockfd,struct sockaddr *srvaddr,socklen_t len);
sockfd:描述符
srvaddr:服务端地址信息
len:地址长度
返回值:成功返回0,失败返回-1。
3.2.4 发送数据
3.2.5 关闭套接字