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

相关推荐
yintele26 分钟前
类人机器人BMS的静电防护
网络·安全·机器人
ICT董老师33 分钟前
通过kubernetes部署nginx + php网站环境
运维·nginx·云原生·容器·kubernetes·php
CCPC不拿奖不改名33 分钟前
网络与API:从HTTP协议视角理解网络分层原理+面试习题
开发语言·网络·python·网络协议·学习·http·面试
liulilittle1 小时前
OPENPPP2 网络驱动模式
开发语言·网络·c++·网络协议·信息与通信·通信
bleach-1 小时前
buuctf系列解题思路祥讲--[SUCTF 2019]CheckIn1--文件上传以及user.ini的应用
nginx·web安全·网络安全·php
Bruce_Liuxiaowei1 小时前
内网探测常用技术方法整理
网络·安全·网络安全
小李独爱秋2 小时前
计算机网络经典问题透视:MD5报文是什么?有什么特点?
网络·网络协议·计算机网络·网络安全·信息与通信·信号处理
June`2 小时前
IO模型全解析:从阻塞到异步(高并发的reactor模型)
linux·服务器·网络·c++
乾元2 小时前
如何把 CCIE / HCIE 的实验案例改造成 AI 驱动的工程项目——从“实验室能力”到“可交付系统”的完整迁移路径
大数据·运维·网络·人工智能·深度学习·安全·机器学习
liulilittle2 小时前
俄罗斯访问欧洲国际线路优化
开发语言·网络·信息与通信·ip·通信·俄罗斯·莫斯科