网络编程——UDP

UDP编程使用套接字(Socket)进行通信。下面是基于UDP协议进行网络编程的基本步骤。

  1. 创建套接字

首先,客户端和服务器都需要通过 socket() 系统调用创建一个UDP套接字。

  1. 配置地址和端口

UDP是无连接的,因此你不需要像TCP一样使用 bind() 来绑定端口。但你仍然需要为发送和接收数据设置目标地址和端口。

  1. 发送和接收数据

1.使用 sendto() 发送数据。

2.使用 recvfrom() 接收数据。

  1. 关闭套接字

所有的套接字操作完成后,使用 close() 来关闭套接字。

  1. UDP 编程示例

以下是一个简单的UDP服务器和客户端的示例,展示了如何在Linux下进行UDP网络编程。

UDP服务器端程序:

UDP服务器端需要执行以下操作:

创建套接字。

绑定到特定端口。

等待接收客户端消息。

发送响应。

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#define PORT 12345
#define MAX_BUFFER_SIZE 1024

int main() {
    int sockfd;
    struct sockaddr_in server_addr, client_addr;
    char buffer[MAX_BUFFER_SIZE];
    socklen_t client_addr_len = sizeof(client_addr);

    // 创建UDP套接字
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        perror("Socket creation failed");
        exit(1);
    }

    // 配置服务器地址
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT);
    server_addr.sin_addr.s_addr = INADDR_ANY;  // 监听所有可用的接口

    // 绑定套接字到地址和端口
    if (bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        perror("Bind failed");
        close(sockfd);
        exit(1);
    }

    printf("UDP server listening on port %d...\n", PORT);

    // 等待接收客户端消息
    while (1) {
        ssize_t recv_len = recvfrom(sockfd, buffer, sizeof(buffer), 0,
                                     (struct sockaddr*)&client_addr, &client_addr_len);
        if (recv_len < 0) {
            perror("Recvfrom failed");
            continue;
        }

        buffer[recv_len] = '\0';  // null terminate received message
        printf("Received from client: %s\n", buffer);

        // 发送响应消息
        const char* response = "Hello, Client!";
        sendto(sockfd, response, strlen(response), 0, 
               (struct sockaddr*)&client_addr, client_addr_len);
    }

    // 关闭套接字
    close(sockfd);
    return 0;
}

UDP客户端程序:

UDP客户端需要执行以下操作:

创建套接字。

配置服务器的IP地址和端口。

使用 sendto() 发送数据。

使用 recvfrom() 接收数据。

关闭套接字。

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#define SERVER_IP "127.0.0.1"
#define PORT 12345
#define MAX_BUFFER_SIZE 1024

int main() {
    int sockfd;
    struct sockaddr_in server_addr;
    char buffer[MAX_BUFFER_SIZE] = "Hello, Server!";

    // 创建UDP套接字
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        perror("Socket creation failed");
        exit(1);
    }

    // 配置服务器地址
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT);
    server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);

    // 发送数据到服务器
    ssize_t send_len = sendto(sockfd, buffer, strlen(buffer), 0,
                              (struct sockaddr*)&server_addr, sizeof(server_addr));
    if (send_len < 0) {
        perror("Sendto failed");
        close(sockfd);
        exit(1);
    }

    // 接收来自服务器的响应
    ssize_t recv_len = recvfrom(sockfd, buffer, sizeof(buffer), 0, NULL, NULL);
    if (recv_len < 0) {
        perror("Recvfrom failed");
        close(sockfd);
        exit(1);
    }

    buffer[recv_len] = '\0';  // Null-terminate received message
    printf("Received from server: %s\n", buffer);

    // 关闭套接字
    close(sockfd);
    return 0;
}
  1. 解释代码

UDP服务器端:

创建套接字:使用 socket() 创建UDP套接字,指定地址族 AF_INET 和套接字类型 SOCK_DGRAM。

绑定端口:使用 bind() 将套接字绑定到指定的端口和地址。这里使用 INADDR_ANY,表示接受来自所有IP地址的连接。

接收数据:服务器通过 recvfrom() 接收客户端发送的数据,recvfrom() 可以返回发送数据的客户端地址信息。

发送数据:使用 sendto() 将响应发送到客户端。

UDP客户端:

创建套接字:使用 socket() 创建UDP套接字,类型为 SOCK_DGRAM。

配置服务器地址:设置目标服务器的IP地址和端口,使用 inet_addr() 将字符串形式的IP转换为 in_addr_t。

发送数据:使用 sendto() 将消息发送到服务器。

接收数据:使用 recvfrom() 接收来自服务器的响应数据。

  1. UDP 编程中的一些注意事项

无连接特性:UDP是无连接的,这意味着客户端和服务器不需要建立连接,只要有目标地址和端口,数据就可以发送。

数据可靠性:UDP不保证数据的顺序、完整性和可靠性,数据包可能丢失、重复或乱序。应用程序需要自行处理数据的可靠性问题(如果需要)。

适用于实时应用:因为UDP的头部较小,传输速度较快,适合用于实时通信,如视频流、语音通话等。

广播和组播:UDP支持广播和组播功能,客户端可以使用广播向多个目标发送消息,服务器可以通过组播接收来自多个客户端的消息。

总结

UDP协议通过简单、轻量的机制进行数据传输,适用于对实时性要求高的场合。Linux下的UDP网络编程通过 socket()、sendto() 和 recvfrom() 等系统调用实现数据发送和接收。虽然UDP不提供可靠的传输机制,但它的高效性使得它在许多实时系统中广泛使用。

相关推荐
yunfuuwqi1 小时前
OpenClaw✅真·喂饭级教程:2026年OpenClaw(原Moltbot)一键部署+接入飞书最佳实践
运维·服务器·网络·人工智能·飞书·京东云
迎仔1 小时前
C-算力中心网络隔离实施方法:怎么搞?
运维·网络
代码游侠1 小时前
C语言核心概念复习——网络协议与TCP/IP
linux·运维·服务器·网络·算法
枷锁—sha2 小时前
【SRC】SQL注入WAF 绕过应对策略(二)
网络·数据库·python·sql·安全·网络安全
Zach_yuan2 小时前
深入浅出 JSONCpp
linux·服务器·网络·c++
ServBay3 小时前
一个下午,一台电脑,终结你 90% 的 Symfony 重复劳动
后端·php·symfony
迎仔4 小时前
B-算力中心网络隔离的必要性:为什么必须隔离?
网络
野指针YZZ5 小时前
一键配置RK3588网络与SSH远程连接
网络·ssh·rk3588
迎仔5 小时前
10-网络安全监控与事件响应:数字世界的智能监控与应急系统
网络·安全·web安全
上海合宙LuatOS6 小时前
LuatOS核心库API——【audio 】
java·网络·单片机·嵌入式硬件·物联网·音视频·硬件工程