笔者上一篇的文章总结的TCP通信协议的特点与TCP回声服务器的代码实现,所以这一次,再对UDP通信协议进行一次总结
UDP 的全称为用户数据报协议(UDP, User Datagram Protocol) 它是一个无连接的传输协议.UDP为应用程序提供了一种无需连接就可以发送封装的IP数据包的方法。
回声服务器是指一种收到客户端发送的消息后,将消息回传至客户端服务器,这种服务器代码简单,但功能健全,非常适合帮助初学者理解网络编程中UDP通信协议。
笔者在此总结一张表概括UDP与TCP的区别
UDP | TCP | |
---|---|---|
是否连接 | 无连接 | 面向连接 |
是否可靠 | 不可靠传输,不使用流量控制和拥塞控制 | 可靠传输,使用流量控制和拥塞控制 |
连接对象个数 | 支持一对一,一对多,多对一和多对多交互通信 | 只能是一对一 |
传输方式 | 面向报文 | 面向字节流 |
适用场景 | 适用于实时应用(IP电话、视频会议、直播等) | 适用于要求可靠传输的应用,例如文件传输 |
服务器端 S | 客户端 C |
---|---|
创建套接字socket | 创建套接字socket |
准备通信地址(服务器的地址) | 准备通信地址(服务器的地址) |
绑定套接字和通信地址 | 连接服务器端S |
接收/发送数据 | 发送/接收数据 |
关闭套接字 | 关闭套接字 |
//创建套接字
//准备通信地址
//绑定socket与通信地址
//接收数据,将接收到的数据存入缓冲区
//发送数据,将缓冲区的数据发送出去
//关闭套接字
//创建套接字
//准备通信地址
//发送数据
//接收数据
//关闭套接字
#include
#include
#include
#include
#include
#include
#include
typedef struct sockaddr* SP;
int main(int argc,const char* argv[])
{
// 创建socket对象
int svr_sock = socket(AF_INET,SOCK_DGRAM,0);
if(0 > svr_sock)
{
perror("socket");
return EXIT_FAILURE;
}
// 准备通信地址(自己的)
struct sockaddr_in svr_addr = {
} , cli_addr = {
};
svr_addr.sin_family = AF_INET;
svr_addr.sin_port = htons(1324);
svr_addr.sin_addr.s_addr = inet_addr("192.168.0.113");
socklen_t addrlen = sizeof(svr_addr);
// 绑定地址与socket对象
if(bind(svr_sock,(SP)&svr_addr,addrlen))
{
perror("bind");
return EXIT_FAILURE;
}
char buf[4096] = {
};
size_t buf_size = sizeof(buf);
for(;;)
{
// 接收数据和来时的地址
size_t ret_size = recvfrom(svr_sock,buf,buf_size,0,(SP)&cli_addr,&addrlen);
if(0 >= ret_size)
{
perror("recvfrom");
// 关闭socket对象
close(svr_sock);
return EXIT_FAILURE;
}
printf("from:%s recv:[%s] bits:%d\n",inet_ntoa(cli_addr.sin_addr),buf,ret_size);
sprintf(buf,"return:%s",inet_ntoa(svr_addr.sin_addr));
// 返回数据
sendto(svr_sock,buf,strlen(buf)+1,0,(SP)&cli_addr,addrlen);
}
}
#include
#include
#include
#include
#include
#include
#include
typedef struct sockaddr* SP;
int main(int argc,const char* argv[])
{
// 创建socket对象
int is_broadcast = 1;
int cli_sock = socket(AF_INET,SOCK_DGRAM,0);
if(0 > cli_sock)
{
perror("socket");
return EXIT_FAILURE;
}
setsockopt(cli_sock,SOL_SOCKET,SO_BROADCAST,&is_broadcast,sizeof(is_broadcast));
// 准备通信地址(服务端的)
struct sockaddr_in svr_addr = {
};
svr_addr.sin_family = AF_INET;
svr_addr.sin_port = htons(1324);
svr_addr.sin_addr.s_addr = inet_addr("192.168.0.255");
socklen_t addrlen = sizeof(svr_addr);
char buf[4096] = {
};
size_t buf_size = sizeof(buf);
for(;;)
{
printf(">>>");
gets(buf);
if(0 == strcmp("quit",buf))
{
printf("退出通信!\n");
close(cli_sock);
return EXIT_SUCCESS;
}
// 向服务器发送数据
sendto(cli_sock,buf,strlen(buf)+1,0,(SP)&svr_addr,addrlen);
// 从服务器接收数据
size_t ret_size = recvfrom(cli_sock,buf,buf_size,0,(SP)&svr_addr,&addrlen);
if(0 >= ret_size)
{
perror("recvfrom");
// 关闭socket对象
close(cli_sock);
return EXIT_FAILURE;
}
printf("from:%s recv:[%s] bits:%d\n",inet_ntoa(svr_addr.sin_addr),buf,ret_size);
}
}
笔者在本文中总结了UDP通信协议与TCP通信协议的区别,同时用代码具体实现了基于UDP通信协议的回声服务器,通过阅读本文,相信一定能帮助读者更加形象的了解TCP/UDP两种通信协议。