# 网络，第 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;
}
```