UDP(User Datagram Protocol,用户数据报协议)提供了比TCP更简单的端到端服务。
UDP只执行两种功能:(1)向IP层添加了另一个寻址(端口)层;(2)它会检测传输中可能发生的数据损坏,并丢弃任何损坏的数据报。
UDP套接字使用前不进行连接,它会保留消息边界。UDP提供的端到端服务是一种“尽力而为”的服务:不保证通过UDP套接字发送的消息将会到达其目的地。这意味着UDP套接字程序必须准备处理消息的丢失和重排。
4.1 UDP客户
与TCP的区别:
(1) 不会调用connect
(2) 使用sentdto和recvfrom发送消息,而不是sent和recv
(3) 只要执行一次接受,UDP套接字会保留消息边界。
UDP客户只与UDP服务器通信。
UDP应答服务器简单的把接受的任何消息发送回它们的任何源发地。
UDP应答客户端:
(1) 把应答字符串发送给服务器
(2) 接受应答
(3)关闭程序
UDP应答客户端udp_echo_client.c程序代码:
#include "practical.h"
#define MAXSTRLEN 1000
int main(int argc, char **argv)
{
if (argc < 3 || argc > 4) {
err_quit("Usage: a.exe <Server Address/Name> <Echo Word> [<Server Prot>/Service]");
}
char *server = argv[1];
char *echo_str = argv[2];
size_t echo_strlen = strlen(echo_str);
if (echo_strlen > MAXSTRLEN) {
err_quit("%s string too long", echo_str);
}
char *service = (argc == 4) ? argv[3] : "echo";
struct addrinfo hint;
bzero(&hint, sizeof(hint));
hint.ai_family = AF_UNSPEC;
hint.ai_socktype = SOCK_DGRAM;
hint.ai_protocol = IPPROTO_UDP;
struct addrinfo *servaddr;
int rtnval = getaddrinfo(server, service, &hint, &servaddr);
if (rtnval != 0) {
err_quit("getaddrinfo() failed:%s", gai_strerror(rtnval));
}
int sock = socket(servaddr->ai_family, servaddr->ai_socktype, servaddr->ai_protocol);
if (sock < 0) {
err_sys("socket() failed");
}
ssize_t nbytes = sendto(sock, echo_str, echo_strlen, 0,
servaddr->ai_addr, servaddr->ai_addrlen);
if (nbytes < 0) {
err_sys("sendto() failed");
} else if (nbytes != echo_strlen) {
err_quit("sentto() error: sent unexpcted number of bytes");
}
struct sockaddr_storage fromaddr;
size_t fromaddrlen = sizeof(fromaddr);
char buf[MAXSTRLEN + 1];
nbytes = recvfrom(sock, buf, MAXSTRLEN, 0, (struct sockaddr*)&fromaddr, &fromaddrlen);
if (nbytes < 0) {
err_sys("recvfrom() failed");
} else if (nbytes != echo_strlen) {
err_quit("recvfrom() error: reveived unexpected number of bytes");
}
if (!sockaddr_equal(servaddr->ai_addr, (struct sockaddr*)&fromaddr)) {
err_quit("recvform(): received a packet form unknown source");
}
freeaddrinfo(servaddr);
buf[echo_strlen] = '