UDP相关
TCP/UDP通信
TCP
面向连接,可靠数据包传输(对于不稳定的网络层,丢包重传)
优点:数据流量稳定、速度稳定、顺序
缺点:传输速度慢,效率低,开销大
场景:数据的完整型要求较高,不追求效率(大数据传输、文件传输)
UDP
无连接的,不可靠的数据报传递(默认还原网络状况)
优点:传输速度快。效率高,开销小
缺点:不稳定,数据流量,速度,顺序
使用场景:对时效性要求较高场合,稳定性其次(游戏、视频会议、视频电话等)
c/s模型流程图(UDP)
实现描述
// recvfrom
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
sockfd: 套接字
buf: 缓冲区地址
len: 缓冲区大小
flags 0
srcaddr: 传出参数,对端地址结构
addrlen: 传入传出参数
返回值为: 成功接收数据字节数|失败:-1(设置error)|0:对端关闭
// 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
srcaddr: 传入,目标地址结构
addrlen: 地址结构长度
返回值为: 成功写出数据字节数|失败:-1,设置errno
1. server端,执行流程:
lfd = socket(AF_INET, STREAM, 0); // SOCK_DGRAM --- 报式协议
bind();
while(1){
recvfrom(lfd,buf,size,addr);
// 处理再回写
sendto(cfd,buf,size,addr);
}
close();
2. client端,执行流程:
connfd = socket(AF_INET, SOCK_DGRAM, 0);
sendto(cfd,buf,size,addr);
recvfrom(lfd,buf,size,addr);
//打印到屏幕
close();
IPC-本地套接字(socket)
Server端:
网络套接字(TCP) | 本地套(domain) |
---|---|
bzero() ---- struct sockaddr_in serv_addr | bzero() ---- struct sockaddr_un serv_addr, clie_addr |
lfd=socket(AF_INET, SOCK_STREAM, 0) | lfd = socket(AF_UNIX, SOCK_STREAM, 0) |
sockaddr_in | sockaddr_un |
struct sockaddr_in srv_addr | struct sockaddr_un srv_addr |
srv_addr.sin_family = AF_INET | srv_addr.sun_family = AF_UNIX |
srv_addr.sin_port = htons(8888) | strcpy(srv_addr.sun_path, “套接字文件名”) |
srv_addr.sin_addr.s_addr = htonl(INADDR_ANY) | len = offsetof(struct sockaddr_un, sun_path) + strlen(“套接字文件名”) |
— | unlink(“套接字文件名”) |
bind(fd, (struct sockaddr *)&srv_addr, sizeof(srv_addr)) | bind(fd, (struct sockaddr *)&srv_addr, len) |
Listen(lfd,128) | Listen(lfd,128) |
cfd = Accept(lfd, ()&clie_addr, &len) | cfd = Accept(lfd, ()&clie_addr, &len) |
Client端:
网络套接字(TCP) | 本地套(domain) |
---|---|
lfd = socket(AF_INET, SOCK_STREAM, 0) | lfd = socket(AF_UNIX, SOCK_STREAM, 0) |
隐式绑定 ip+port | bzero() ---- struct sockaddr_un clie_addr |
— | clie_addr.sun_family = AF_UNIX |
— | strcpy(clie_addr.sun_path, “client套接字文件名”) |
— | len = offsetof(sockaddr_un, sun_path) + strlen() |
— | unlink( “client套接字文件名”) |
— | bind(lfd, (struct sockaddr *) &clie_addr, len) |
bzero() ---- struct sockaddr_in serv_addr | bzero() ---- struct sockaddr_un serv_addr |
serv_addr.sin_family = AF_INET | serv_addr.sun_family = AF_UNIX |
inet_pton(AF_INT, “Server_IP”, &sin_addr.s_addr) | strcpy(serv_addr.sun_path, “server套接字文件名”) |
serv_addr.sin_port = htons(“Server_Port”); | len = offsetof(sockaddr_un, sun_path) + strlen() |
connect(lfd, &serv_addr, sizeof()) | connect(lfd, &serv_addr, len) |