文章目录
一、UDP
1、发送信息过程图解
2、函数解析
(1)创建套接字 socket
- 函数格式:int socket(int domain,int type,int protocol);
- 头文件:#include <sys/socket.h>
———————————————分割线————————————————
-
domian:指定网络层用什么协议
地址域信息(参数类型): AF_INET:ipv4网络 AF_INET6:ipv6网络 AF_UNIX:本地域套接字(用于本地进程通信)
-
type:创建套接字类型
SOCK_DGRAM:用户数据报套接字(UDP协议) SOCK_STREAM:流式套接字(TCP协议)
-
protocol:表示使用套接字类型默认协议
头文件:#include <netinet/in.h> IPPRPTO_UDP:17 IPPRPTO_TCP:6
-
函数返回值:返回套接字描述符(本质上就是一个文件描述符)
成功:大于等于0 失败:小于0
-
举个例子:int sockfd = socket(AF_INRT, SOCK_DREAM, IPPROTO_UDP);
创建了一个名为sockfd的套接字,采用ipv4网络和UDP协议的数据报套接字。
(2)绑定地址信息 bind
- 函数格式:int bind(int sockfd,const struct sockaddr * addr,socklen_t addrlen);
———————————————分割线————————————————
-
sockfd:socket函数返回的套接字描述符,将创建出来的套接字、网卡以及端口进行绑定。
-
addr:地址信息结构
struct sockaddr //通用地址信息结构 { sa_family_t sa_family; /*地址域信息,占两个字节。 决定了当前使用什么网络层协议 (AF_INET、AF_INET6、AF_UNIX)*/ char sa_data[14]; /*本质上任何网络程序都不会直接填充 这14个字节的字符数组*/ }
-
addrlen:地址信息结构的长度
(3)发送接口 sendto
- 函数格式:ssize_t sendto(int sockfd,const void * buf,size_t len,int flags,const struct sockaddr * dest_addr.socklen_t addrlen);
———————————————分割线————————————————
-
sockfd:套接字描述符
-
buf:要发送的数据
-
len:发送数据的长度
-
flags:0(零——阻塞发送)
-
dest_addr:目标主机的地址信息结构(IP地址+端口号)
-
addrlen:目标主机地址信息结构的长度
-
返回值
成功:返回具体发送的字节数量 失败:返回-1
(4)接收接口 recvfrom
- 函数格式:ssize_t recvfrom(int sockfd,void * buf,size_t len,int flags,struct sockaddr * src_addr.socklen_t * addrlen);
———————————————分割线————————————————
-
sockfd:套接字描述符
-
buf:将数据接收到buf中
-
len:buf最大接受能力
-
flags:0(零——阻塞接收)
-
src_addr:这个数据来源的主机的地址信息结构
-
addrlen:输入输出型参数
-
返回值
成功:接收的字节数量 失败:返回-1
(5)关闭套接字 close
- 函数格式:close(int sockfd);
二、TCP
1、三次握手与发送信息过程图解
2、四次挥手过程图解
2、函数解析
TCP的创建套接字和绑定套接字与UDP相同,可见UDP部分内容。
(1)监听 listen
- 函数格式:int listen(int sockfd,int backlog);
———————————————分割线————————————————
- sockfd:套接字描述符
- backlog:已完成连接队列的大小
(2)接收新连接 accept
- 函数格式:int accept(int sockfd,struct sockaddr * addr,socklen_t * addrlen);
- 从已经完成连接队列中获取已经完成三次握手的连接(注:没有连接的时候,调用accept也会阻塞)
———————————————分割线————————————————
-
addr:客户端的地址信息结构(客户端IP地址与端口)
-
addrlen:客户端地址信息结构的长度
-
返回值
成功:返回的是新连接的套接字描述符(图解见下) 失败:返回-1
多个客户端会与TCP服务器的监听套接字进行三次握手从而建立连接,建立连接后每个客户端都有与之一一对应的通信套接字进行通信。
(3)发起连接 connect
-
函数格式:int connect(int sockfd,const struct sockaddr * addr,socklen_t * addrlen);
-
addr:服务器的地址信息结构(客户端IP地址与端口)
-
返回值
成功:返回0 失败:小于0
(4)发送数据 send
- 函数格式:ssize_t send(int sockfd,const void * buf,size_t len,int flags);
———————————————分割线————————————————
-
sockfd:accept返回的套接字描述符
-
buf:待要发送的数据
-
len:发送数据的长度
-
flags
0(零):阻塞发送 MSG_OOB:发送带外数据
-
返回值
成功:返回具体发送的字节数量 失败:返回-1
(5)接收数据 recv
- 函数格式:ssize_t recv(int sockfd,void * buf,size_t len,int flags);
(注:如果连接没有数据,那么调用recv会阻塞)
———————————————分割线————————————————
-
sockfd:accept返回的套接字描述符
-
buf:将接收的数据放到这里
-
len:buf的最大接受能力
-
flags:0(零——阻塞接收)
-
src_addr:这个数据来源的主机的地址信息结构
-
返回值
大于0:正常接收了多少字节数据 等于0:对端将连接关闭 小于0:接收失败
(5)关闭套接字 close
- 函数格式:close(int sockfd);