目录
[一、UDP (传输层,用户数据报协议)](#一、UDP (传输层,用户数据报协议))
一、UDP (传输层,用户数据报协议)
UDP(User Datagram Protocol)用户数据报协议,是不可靠的无连接的协议。在数据发送前,因为不需要进行连接,所以可以进行高效率的数据传输。
适用情况:
1、发送小尺寸数据(如对DNS服务器进行IP地址查询时)
2、在接收到数据,给出应答较困难的网络中使用UDP。
3、适合于广播/组播式通信中。
4、MSN/QQ/Skype等即时通讯软件的点对点文本通讯以及音视频通讯通常采用UDP协议
5、流媒体、VOD、VoIP、IPTV等网络多媒体服务中通常采用UDP方式进行实时数据传输
二、服务器Server的创建
代码如下:
cpp
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
if (argc != 2)
{
printf("usage:<port>\n");
return -1;
}
// 1.创建套接字
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
{
perror("sockfd err");
return -1;
}
printf("sockfd:%d\n", sockfd);
// 2.绑定ip+port
struct sockaddr_in saddr, caddr; // 头文件查看 man 7 ip
saddr.sin_family = AF_INET; // sin_family//协议族AF_INET
saddr.sin_port = htons(atoi(argv[1])); // 端口号port
socklen_t addrlen = sizeof(saddr);
// 使能开关
#if 0
saddr.sin_addr.s_addr = inet_addr(argv[1]);//ip
#else
// 绑定电脑上的所有可用IP给服务器
saddr.sin_addr.s_addr = INADDR_ANY; // ip
// saddr.sin_addr.s_addr = inet_addr("0.0.0.0"); // ip
#endif
if (bind(sockfd, (struct sockaddr *)&saddr, addrlen) < 0)
{
perror("bind err");
return -1;
}
printf("bind success\n");
// 3.接收消息
#define N 1024
char buf[N] = {};
while (1)
{
size_t res = recvfrom(sockfd, buf, N, 0, (struct sockaddr *)&caddr, &addrlen);
if (res < 0)
{
perror("recvfrom err");
return -1;
}
else if (res > 0)
{
if (strcmp(buf, "quit") == 0)
{
printf("Client Exist\n");
close(sockfd);
break;
}
printf("ip:%s port:%d\n", inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));
printf("buf:%s\n", buf);
memset(buf, 0, N);
}
}
return 0;
}
三、客户端Client的创建
代码如下:
cpp
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
if (argc != 3)
{
printf("usage:<ip> <port>\n");
return -1;
}
// 1.创建数据报套接字
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
{
perror("sockfd err");
return -1;
}
printf("sockfd:%d\n", sockfd);
// 接收
// recvfrom(sockfd,&buf,N,0,(struct sockaddr *)&saddr, &len);
// 2.发送
//后面函数需要传结构体指针类型的参数,需要定义一个填充好的结构体
#define N 64
struct sockaddr_in saddr; // 头文件查看 man 7 ip
saddr.sin_family = AF_INET; // sin_family//协议族AF_INET
saddr.sin_port = htons(atoi(argv[2])); // 端口号port
saddr.sin_addr.s_addr = inet_addr(argv[1]); // ip
socklen_t len = sizeof(saddr);
char buf[N] = {};
while (1)
{
gets(buf);
ssize_t Lo = sendto(sockfd, &buf, N, 0, (struct sockaddr *)&saddr, len);//接收消息
if(strcmp(buf,"quit")==0)//跳出while循环判断条件
{
close(sockfd);
break;
}
memset(buf,0,N);
}
return 0;
}
// 通用结构体:相当于预留一个空间
// struct sockaddr {
// sa_family_t sa_family;
// char sa_data[14];
// }
// ipv4的结构体
// struct sockaddr_in {
// sa_family_t sin_family; //协议族AF_INET
// in_port_t sin_port; //端口
// struct in_addr sin_addr;
// };
// struct in_addr {
// uint32_t s_addr; //IP地址
// };
四、效果实现(描述)
sockfd:X
bind success
ip:XXXX.XXXX.XXXX.XXXX port:XXXXX
buf:ggggggggg
Client Exist