🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 网络,第 6 部分:创建 UDP 服务器 > 原文:<https://github.com/angrave/SystemProgramming/wiki/Networking%2C-Part-6%3A-Creating-a-UDP-server> ## 如何创建 UDP 服务器? 有多种函数调用可用于发送 UDP 套接字。我们将使用较新的 getaddrinfo 来帮助设置套接字结构。 请记住,UDP 是一种简单的基于数据包('data-gram')协议;两个主机之间没有建立连接。 首先,初始化提示 addrinfo 结构以请求 IPv6 被动数据报套接字。 ```c memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; // INET for IPv4 hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_PASSIVE; ``` 接下来,使用 getaddrinfo 指定端口号(我们不需要指定主机,因为我们正在创建服务器套接字,而不是将数据包发送到远程主机)。 ```c getaddrinfo(NULL, "300", &hints, &res); sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); bind(sockfd, res->ai_addr, res->ai_addrlen); ``` 端口号&lt;1024,因此程序将需要`root`权限。我们也可以指定服务名称而不是数字端口值。 到目前为止,调用类似于 TCP 服务器。对于基于流的服务,我们将调用`listen`并接受。对于我们的 UDP 服务,我们可以开始等待数据包到达套接字 - ```c struct sockaddr_storage addr; int addrlen = sizeof(addr); // ssize_t recvfrom(int socket, void* buffer, size_t buflen, int flags, struct sockaddr *addr, socklen_t * address_len); byte_count = recvfrom(sockfd, buf, sizeof(buf), 0, &addr, &addrlen); ``` addr 结构将保存有关到达数据包的发送方(源)信息。注意`sockaddr_storage`类型足够大,可以容纳所有可能类型的套接字地址(例如 IPv4,IPv6 和其他套接字类型)。 ## 完整代码 ```c #include <string.h> #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <unistd.h> #include <arpa/inet.h> int main(int argc, char **argv) { int s; struct addrinfo hints, *result; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; // INET for IPv4 hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_PASSIVE; getaddrinfo(NULL, "300", &hints, &res); int sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (bind(sockfd, res->ai_addr, res->ai_addrlen) != 0) { perror("bind()"); exit(1); } struct sockaddr_storage addr; int addrlen = sizeof(addr); while(1){ char buffer[1000]; ssize_t byte_count = recvfrom(sockfd, buf, sizeof(buf), 0, &addr, &addrlen); buffer[byte_count] = '\0'; } printf("Read %d chars\n", len); printf("===\n"); printf("%s\n", buffer); return 0; } ```