一、UDP通信流程
客户端
- 创建一个套接字。
- 绑定地址信息。一般情况下编写客户端程序时不用自己绑定地址信息,会让操作系统默认分配一个空闲的端口。因为一个端口只能被一个进程绑定。
- 发送数据。
- 接收数据。
- 关闭套接字。
服务端
- 创建一个套接字。
- 绑定地址信息(port和ip)。port表明服务端进程在哪一个端口上侦听数据;ip表明服务端进程在哪一个机器上接收数据。
- 接收数据。
- 发送数据。
- 关闭套接字。
二、UDP编程套接字接口
-
创建套接字
int socket(int domain, int type, int protocol);- 返回值:返回套接字的操作句柄,其实就是一个文件描述符,在这里一般称之为套接字描述符。
- domain:地址域,传入协议的版本。即就是设置网络层使用什么协议。
- ipv4对应宏AF_INET
- ipv6对应宏AF_INET6
- type:套接字类型
- 流式套接字:默认类型是tcp,不支持udp,对应宏SOCK_STREAM。
- 数据包套接字:默认类型是udp,不支持tcp,对应宏SOCK_DGRAM。
- protocol:指定套接字所使用的协议
- IPPROTO_TCP:使用TCP协议。
- IPPROTO_UDP:使用UDP协议。
-
绑定地址信息
int bind(int sock_fd, const socket* addr, socklen_t addrlen);-
sock_fd: 套接字描述符。
-
addr:地址信息,ip+port。
struct sockaddr { sa_family_t sa_family; //用来填充地址域的(AF_INET),占用两个字节 char sa_data[14]; //填充地址信息,ip+port }
设计这个结构体是为了通用各种协议,在进行具体协议地址信息绑定的时候,填充不同的结构体,之后将结构体的对象的地址,强转传参给bind()。
-
addrlen:地址信息的长度。防止有的协议的地址信息长度大于16个字节,所以传递地址信息长度告诉bind函数应该如何去解析地址信息。
-
-
发送数据
ssize_t sendto(int sock_fd, const void* buf, size_t len, int flags, const struct sockaddr* dest_addr, socklen_t addrlen);- sock_fd:套接字描述符。
- buf:待发送的数据。
- len:发送的数据长度。
- flags:一般用0表示阻塞发送。
- dest_addr:目标主机地址信息(标识这条数据要去往哪一个主机上面的哪一个的进程)。
- addrlen:地址信息长度。
-
接收数据
ssize_t recvfrom(int sock_fd, void* buf, size_t len, int flags, struct sockarrd* src_addr, socklen_t* addrlen);- sock_fd:套接字描述符。
- buf:从接收缓冲区当中拿到的数据放到哪一个buffer当中。
- len:buffer的最大长度,意味着最大可以接收多少数据,注意要预留"\0"的位置。
- flags:一般用0表示阻塞接收。
- src_addr:源主机的地址信息(标识这条数据从哪一个主机上面的哪一个的进程来的)。
- addrlen:注意这里是一个socklen_t*类型,表示地址信息长度,同时是一个输入输出型参数;
-
关闭套接字
close(int sock_fd);