Skip to content

Latest commit

 

History

History
89 lines (64 loc) · 2.73 KB

60.md

File metadata and controls

89 lines (64 loc) · 2.73 KB

网络,第 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 被动数据报套接字。

memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6; // INET for IPv4
hints.ai_socktype =  SOCK_DGRAM;
hints.ai_flags =  AI_PASSIVE;

接下来,使用 getaddrinfo 指定端口号(我们不需要指定主机,因为我们正在创建服务器套接字,而不是将数据包发送到远程主机)。

getaddrinfo(NULL, "300", &hints, &res);

sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
bind(sockfd, res->ai_addr, res->ai_addrlen);

端口号<1024,因此程序将需要root权限。我们也可以指定服务名称而不是数字端口值。

到目前为止,调用类似于 TCP 服务器。对于基于流的服务,我们将调用listen并接受。对于我们的 UDP 服务,我们可以开始等待数据包到达套接字 -

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 和其他套接字类型)。

完整代码

#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;
}