socket套接字编程--UCP通信流程
网络编程-socket套接字编程
在网络通信中,总是两台主机(C/S)之间的通信
客户端clinet:主动发出请求;
服务端sever:被动接受请求并给予响应
c/s架构-客户端服务器模式
还有另外的通信模式例如P2P在后面章节会有介绍
程序员可通过套接字对运输层实现控制:
- 选择运输层协议;
- 可以设定几个参数,如最大缓存和最大报文段长度等。
传输层协议-TCP/UDP
- TCP:传输控制协议:面向连接,可靠传输,面向字节流
特性:传输数据的安全性优于实时性–文件传输 - UDP:用户数据协议:无连接,不可靠,面向数据报
特性:传输数据的实时性优于安全性–视频传输
UDP通信流程
- 创建套接字
在内核中创建一个socket结构体,向用户返回操作句柄
int socket(int domain,int type,int protocol)
domain 地址域:地址结构;例如IPV4(AF_INET)、IPV6(AF_INET6)
type 套接字类型:数据报类型(SOCK_DGRAM)、字节流类型(SOCK_STREAM)
protocol协议类型:0为按套接字默认选择
数据报默认UDP;字节流默认TCP
或者填入TCP协议(IPPROTO_TCP);UDP协议(IPPROTO_UDP)
返回值:文件描述符 - 为套接字绑定地址信息
为创建的套接字填充IP地址和端口信息
int bind(int sockfd,struct sockaddr* addr,socklen_t addrlen);
sockfd:已创建的套接字返回的操作句柄
addr:地址信息结构体的首地址
addrlen:地址信息长度
返回值成功返回0,失败返回-1;
由于地址信息结构的多样化,一个函数无法处理全部的地址信息结构
为解决此问题,设立地址信息结构化模板struct sockaddr
该模板大小为所有地址信息结构中最大的,对于一些较小的地址信息结构会在结构体末尾加入补全位
在所有地址信息结构的头两个字节用来存放地址结构的类型,相当于将各类地址信息结构的名称。
在bind函数内部再根据函数名称进入到相应的地址信息结构处理段
例如:我要定义一个IPV4的地址信息结构
struct sockaddr_in tmp;
tmp.sin_family = AF_INET;
tmp.sin_port =···;
tmp.sin_addr = ···;
int ret = bind(sockfd,(struct sockaddr*)tmp,socklen_t len);
- 接收数据
从socket的接收缓冲区中取出网卡接收到的数据
int recvfrom(int sockfd,char* buf,int buf_len,int flag,struct sockaddr* peer_addr,socklen_t*addr_len);
sockfd:指定内核中的socket结构体–从哪个socket的缓冲区中取出数据
buf:用户态缓冲区,用于存放从内核中拷贝出来的数据
buf_len:想要获取的数据长度,不能大于buf的长度
flag:默认为0–阻塞接收–接收缓冲区中没有数据的时候阻塞等待
peer_addr:地址缓冲区首地址–用于获取发送这个数据的源端地址–告诉我们这个数据是谁发送的
addr_len:输入输出型参数–用于指定想要多长的地址信息;并用于返回实际获取的地址长度
返回值:成功返回实际接收数据的长度,失败返回-1; - 发送数据
将数据放到socket的发送缓冲区
ssize_t sendto(int sockfd,char* data,int data_len,int flag ,struct sockaddr* dest_addr,socklen_t addr_len);
sockfd:指定内核中的socket结构体–从哪个socket的缓冲区中取出数据
data:要发送的首地址
data_len:要发送的数据长度
flag:默认为0–阻塞发送数据–发送缓冲区中满的时候阻塞等待
dest_addr:目的端的地址信息首地址–用于告诉socket这个数据发送给谁
addr_len:地址信息长度输入型参数
返回值:成功返回实际发送数据的长度,失败返回-1; - 关闭套接字
释放资源
int close(int fd)
套接字也称作API-应用程序编程接口
- 字节序转换接口-整数与整数的转化
#include
uint32_t htonl(uint32_t hostlong); //将4字节的整数转换为网络字节序整数
uint16_t htons(uint16_t hostshort); //将2字节的整数转化为网络字节序整数
uint32_t ntohl(uint32_t netlong); //将4字节的网络字节序整数转化为主机字节序整数
uint16_t ntohs(uint16_t netshort); //将2字节的网络字节序整数转化为主机字节序整数
- 字节序转换接口-整数与字符串的转化
int inet_pton(int af,const char* src,void* dst);—字符串-整数
af:地址域-说明是哪种地址结构
src:字符串的IP地址
dst:转化后的网络字节序整数的IP地址
in_addr_t inet_addr(char* ip_str)—将点分2十进制字符串IP地址转换位网络字节序的整数IP地址
char* inet_ntoa(struct in_addr sin_addr)—将网络字节序IP地址转换位字符串IP地址,并返回字符串首地址
const char* inet_ntop(int af,const void* dst,socklen_t size);—整数-字符串
af:地址域
src:网络字节序的整数IP地址
dst:缓冲区,接受转化后的字符串IP地址
size:缓冲区长度
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
