问题
如何使用 UDP 进行数据收发?
再论 UDP 协议
UDP 是无连接的 (不可靠的,无应答消息,数据包无序号标识)
UDP 是面向数据包的,对应用层数据既不合并也不拆分 (保留数据包边界)
UDP 没有拥塞控制,网络出现的拥塞不会使源主机的发送速率降低
UDP 支持一对一、一对多、多对一和多对多的交互通信
UDP 消息头开销小,只有 8 个字节 (TCP 消息头共 20 个字节)
UDP 和 IP 的区别
UDP 是建立于 IP 之上的数据传输协议
- IP 负责将 UDP 数据包从源主机传输到目标主机
- UDP 则将应用层数据投递到目标 socket (端口号)
UDP 几乎 "继承" 了 IP 传输的特性
UDP 数据收发
?
UDP 编程模式?
编程实验
?client.c
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
int main()
{
int sock = 0;
struct sockaddr_in remote = {0};
struct sockaddr_in addr = {0};
char input[128] = {0};
char buf[128] = {0};
int r = 0;
socklen_t len = 0;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(6666);
remote.sin_family = AF_INET;
remote.sin_addr.s_addr = htonl(INADDR_ANY);
remote.sin_port = htons(8888);
if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
printf("client socket error\n");
return -1;
}
if(bind(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0)
{
printf("udp client bind errpr\n");
return -1;
}
while(1)
{
printf("Input: ");
scanf("%s", input);
len = sizeof(remote);
sendto(sock, input, strlen(input), 0, (struct sockaddr*)&remote, len);
r = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr*)&remote, &len);
if(r > 0)
{
buf[r] = 0;
printf("Receive: %s\n", buf);
}
}
close(sock);
}
server.c
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
int main()
{
int server = 0;
struct sockaddr_in addr = {0};
struct sockaddr_in remote = {0};
char buf[128] = {0};
int len = 0;
socklen_t r = 0;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(8888);
server = socket(PF_INET, SOCK_DGRAM, 0);
if(server < 0)
{
printf("server socket error\n");
return -1;
}
if(bind(server, (struct sockaddr*)&addr, sizeof(addr)) == -1)
{
printf("udp server bind error\n");
return -1;
}
printf("udp server start success!\n");
while(1)
{
len = sizeof(remote);
r = recvfrom(server, buf, sizeof(buf) - 1, 0, (struct sockaddr*)&remote, &len);
if(r > 0)
{
buf[r] = 0;
printf("len = %d\n", r);
printf("receive = %s\n", buf);
printf("remote address = %s\n", inet_ntoa(remote.sin_addr));
printf("port = %d\n", ntohs(remote.sin_port));
sendto(server, buf, strlen(buf), 0, (struct sockaddr*)&remote, sizeof(remote));
}
}
close(server);
return 0;
}
UDP 在数据收发前不需要先建立连接,只需要在收发数据的时候指定好对端的 IP 地址和端口号即可,客户端不需要收发数据前不需要绑定 Socket 和 地址,如果未绑定,那么就会随机指定一个可用的 IP 地址和端口号。
程序运行结果如下所示:
思考?
如何进行一对多的 UDP 数据发送?
|