旅游网站设计规划书,网站建设好后如何连接服务器,贵阳市做网站的公司,网站托管内容UDP编程 UDP#xff1a;全双工通信、面向无连接、不可靠 UDP#xff08;User Datagram Protocol#xff09;用户数据报协议#xff0c;是不可靠的无连接的协议。在数据发送前#xff0c;因为不需要进行连接#xff0c;所以可以进行高效率的数据传输。 适用场景 发送小尺寸…UDP编程 UDP全双工通信、面向无连接、不可靠 UDPUser Datagram Protocol用户数据报协议是不可靠的无连接的协议。在数据发送前因为不需要进行连接所以可以进行高效率的数据传输。 适用场景 发送小尺寸数据如对DNS服务器进行IP地址查询时 适合于广播/组播式通信中。 MSN/QQ/Skype等即时通讯软件的点对点文本通讯以及音视频通讯通常采用UDP协议 通信流程 函数接口 socket int socket(int domain, int type, int protocol);
功能创建套接字
参数domain协议族AF_UNIX, AF_LOCAL 本地通信AF_INET ipv4AF_INET6 ipv6type套接字类型SOCK_STREAM:流式套接字SOCK_DGRAM数据报套接字SOCK_RAW原始套接字protocol协议 - 填0 自动匹配底层 根据type系统默认自动帮助匹配对应协议传输层IPPROTO_TCP、IPPROTO_UDP、IPPROTO_ICMP网络层htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL)返回值成功 文件描述符失败 -1更新errnobind int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
功能绑定
参数socket套接字addr用于通信结构体 (提供的是通用结构体需要根据选择通信方式填充对应结构体-通信当时socket第一个参数确定) addrlen结构体大小 返回值成功 0 失败-1,更新errno通用结构体
struct sockaddr {sa_family_t sa_family;char sa_data[14];
}ipv4通信结构体
struct sockaddr_in {sa_family_t sin_family;in_port_t sin_port; struct in_addr sin_addr;
};
struct in_addr {uint32_t s_addr;
};本地通信结构体
struct sockaddr_un {sa_family_t sun_family; /* AF_UNIX */char sun_path[108]; /* pathname */}; recvfrom ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
功能接收数据
参数sockfd套接字描述符buf:接收缓存区的首地址len接收缓存区的大小flags0src_addr:发送端的网络信息结构体的指针addrlen发送端的网络信息结构体的大小的指针
返回值成功接收的字节个数失败-10:客户端退出 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发送缓存区的大小flags0src_addr:接收端的网络信息结构体的指针addrlen接收端的网络信息结构体的大小
返回值 成功发送的字节个数失败-1服务器 #include stdio.h
#include stdlib.h
#include sys/types.h
#include sys/socket.h
#include netinet/in.h
#include netinet/ip.h
#include unistd.h
#include arpa/inet.h
#include string.h
char buf[128];
int main(int argc, char const *argv[])
{// 1.创建数据报套接字socketint sockfd socket(AF_INET, SOCK_DGRAM, 0);if (sockfd 0){perror(socket err);return -1;}printf(sockfd:%d\n, sockfd);// 2.指定网络信息struct sockaddr_in saddr, caddr;saddr.sin_family AF_INET;saddr.sin_port htons(atoi(argv[1]));saddr.sin_addr.s_addr inet_addr(0.0.0.0);int len sizeof(caddr);// 3.绑定套接字bindif (bind(sockfd, (struct sockaddr *)saddr, sizeof(saddr)) 0){perror(bind err);return -1;}printf(bind ok\n);// 4.接收、发送消息recvfrom sendto)while (1){int ret recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)caddr, len);if (ret 0){perror(recvfrom err);return -1;}else{printf(port:%d\tip:%s\tbuf:%s\n, ntohs(caddr.sin_port), inet_ntoa(caddr.sin_addr), buf);memset(buf, 0, sizeof(buf));}}// 5.关闭套接字closeclose(sockfd);return 0;
}客户端 #include stdio.h
#include stdlib.h
#include sys/types.h
#include sys/socket.h
#include netinet/in.h
#include netinet/ip.h
#include unistd.h
#include arpa/inet.h
#include string.h
char buf[128];
int main(int argc, char const *argv[])
{// 1.创建数据报套接字socketint sockfd socket(AF_INET, SOCK_DGRAM, 0);if (sockfd 0){perror(socket err);return -1;}printf(sockfd:%d\n, sockfd);// 2.指定网络信息struct sockaddr_in caddr;caddr.sin_family AF_INET;caddr.sin_port htons(atoi(argv[2]));caddr.sin_addr.s_addr inet_addr(argv[1]);// 3.接收、发送消息recvfrom sendtowhile (1){fgets(buf, sizeof(buf), stdin);sendto(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)caddr, sizeof(caddr));if (strcmp(buf, quit\n) 0)break;}// 4.关闭套接字closeclose(sockfd);return 0;
}udp丢包 udp丢包 丢包原因 1、服务未启动或出现故障但是数据包依然发送出去目标地址和端口没有任何进程在监听这些数据包将被丢弃。 2、缓冲区满数据包溢出丢失。在实际情况中如果处理的速度比较慢会导致数据包堆积在缓冲区当缓冲区满时发送的数据无处存放就会丢失。另一种情况是发送的数据包非常大时可能这个数据包直接超出了缓冲区的大小也会导致数据丢失。最后一种情况和第一种差不多由于发送的速率过快导致处理不及时。 解决方案接收处理分离 可以使用多进程来处理数据与接收数据使用不同的线程互不影响这样不会导致数据包的接收速度所以缓冲区不会堆积避免数据包的丢失。手动创建了一个本地数据缓冲区使用一个列表将接收的数据存储使用多进程不断处理。这里相当于队列是一个本地缓冲区可以避免数据丢包但是需要注意的是本地缓冲区不能也不能超过大小。