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

相关推荐
比兔代理8 小时前
正向代理与反向代理技术辨析,为什么代理 IP 属于正向代理
服务器·网络·http·ip
damoluomu8 小时前
国产企业级 PHP CMS:哪些能免费商用
php
小贺儿开发9 小时前
Unity 家居视频遥控(细节优化)
科技·unity·程序员·udp·视频·工具·通信
Ivanqhz10 小时前
SVD++算法
java·服务器·网络·深度学习·神经网络
郑州光合科技余经理12 小时前
同城外卖小程序开发:下单成功后,后台导出能不能对上用户端状态
开发语言·前端·git·后端·uni-app·php·ai编程
MyFreeIT12 小时前
Android PHP Manual
php
迪康Defender12 小时前
终端安全实战:如何高效解决企业U盘泄密与管控难题
运维·网络·安全·web安全·终端安全管理
网安小学生(兼顾数据库版)12 小时前
固件+软件供应链:ONEKEY+Mend如何实现全链路安全覆盖
网络·安全·web安全
学习中的码虫13 小时前
网络编程5
服务器·网络
GPU实战笔记14 小时前
本地跑不动 llama.cpp,临时租云 GPU 怎么搭?从启动服务到环境复用
java·服务器·网络·人工智能·深度学习·llama