网络编程——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不提供可靠的传输机制,但它的高效性使得它在许多实时系统中广泛使用。

相关推荐
两个人的幸福10 天前
Windows 桌面应用自研 PHP 队列(下):完整代码与六大工程化优化
php
BingoGo12 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
JaguarJack12 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
用户30745969820713 天前
PHP 扩展——从入门到理解
php
鹏仔先生14 天前
拷贝漫画APP下载页PHP程序,后台带免费AI写作
php
网络研究院14 天前
2026年网络安全
网络·安全·法律·法规·趋势·发展
酣大智14 天前
ARP代理--工作原理
运维·网络·arp·arp代理
云水一下14 天前
从零开始学 PHP 系列(一):PHP 的前世今生与开发环境搭建
开发语言·php
treesforest14 天前
AI安全系统如何识别异常访问?IP风险识别正在成为关键能力
网络·人工智能·tcp/ip·安全·web安全
shushangyun_14 天前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化