UDP通信原理及网络编程

news/2024/5/18 15:14:00 标签: 网络, udp, 网络协议

当涉及到网络通信时,UDP(User Datagram Protocol)是一种常见的选择,它是一种快速而轻量级的协议,特别适用于一些实时性要求高、能够容忍少量数据丢失的应用场景。在本篇博客中,我们将深入探讨UDP协议的使用方法以及一些示例代码。

一:UDP简介

UDP是一种无连接的协议,它允许数据包立即发送,无需建立和断开连接。UDP的特点包括:

- **快速传输**:由于UDP的头部开销较小,数据包传输速度较快,适用于需要实时传输的应用。

- **无可靠性**:UDP不保证数据包的可靠性传输,不保证数据包的顺序到达,也不保证数据包不会丢失。

- **广播和多播**:UDP支持广播和多播,可以将数据包发送到多个接收者。

二:UDP函数的使用方法

1.创建套接字

在UDP通信中,首先需要创建套接字,套接字是数据传输的端点。下面是使用C语言中的`socket`函数创建UDP套接字的示例:

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>

int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
    perror("socket failed!");
    exit(1);
}

2.指定目标地址和端口

在UDP通信中,客户端需要指定要连接的服务器的IP地址和端口号,而服务器需要绑定一个IP地址和端口号以侦听传入的数据包。下面是一个示例:

2.1客户端指定目标地址和端口:
struct sockaddr_in serveraddr;
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
serveraddr.sin_port = htons(12345);
2.2服务器绑定地址和端口:
struct sockaddr_in serveraddr;
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = INADDR_ANY;
serveraddr.sin_port = htons(12345);
bind(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr));

3.发送和接收数据

使用`sendto`函数发送数据包,`recvfrom`函数接收数据包。以下是示例代码:

3.1发送数据包:
char buffer[] = "Hello, UDP Server!";
sendto(sockfd, buffer, strlen(buffer), 0, (struct sockaddr*)&serveraddr, sizeof(serveraddr));
3.2接收数据包:
char buffer[BUFFER_SIZE];
recvfrom(sockfd, buffer, BUFFER_SIZE, 0, NULL, NULL);

 4.处理数据和错误

一旦接收到数据,您可以在应用层对其进行处理和解析。由于UDP不提供可靠性传输,您需要处理丢失的数据包、重复的数据包以及超时等情况,以确保数据的完整性和可靠性。

5.关闭套接字

当通信完成后,不要忘记关闭套接字以释放资源:

close(sockfd);

三:示例:UDP客户端和服务器

以下是一个简单的UDP客户端和服务器示例,演示UDP通信的基本原理和函数的使用方法。

UDP服务器示例:


// 服务器端代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>

#define PORT 12345
#define BUFFER_SIZE 1024

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

    // 创建UDP套接字
    server_socket = socket(AF_INET, SOCK_DGRAM, 0);
    if (server_socket < 0) {
        perror("Error in socket");
        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(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        perror("Error in bind");
        exit(1);
    }

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

    while (1) {
        // 接收客户端消息
        ssize_t recv_len = recvfrom(server_socket, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&client_addr, &client_addr_len);
        if (recv_len < 0) {
            perror("Error in recvfrom");
            exit(1);
        }

        // 打印客户端消息
        buffer[recv_len] = '\0';
        printf("Received message from client: %s\n", buffer);

        // 回复客户端
        if (sendto(server_socket, buffer, recv_len, 0, (struct sockaddr *)&client_addr, client_addr_len) < 0) {
            perror("Error in sendto");
            exit(1);
        }
    }

    // 关闭套接字
    close(server_socket);

    return 0;
}

UDP客户端示例:


// 客户端代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>

#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 12345
#define BUFFER_SIZE 1024

int main() {
    int client_socket;
    struct sockaddr_in server_addr;
    char buffer[BUFFER_SIZE];
    const char *message = "Hello, UDP Server!";

    // 创建UDP套接字
    client_socket = socket(AF_INET, SOCK_DGRAM, 0);
    if (client_socket < 0) {
        perror("Error in socket");
        exit(1);
    }

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

    // 发送消息到服务器
    if (sendto(client_socket, message, strlen(message), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        perror("Error in sendto");
        exit(1);
    }

    printf("Message sent to server: %s\n", message);

    // 接收服务器回复
    ssize_t recv_len = recvfrom(client_socket, buffer, BUFFER_SIZE, 0, NULL, NULL);
    if (recv_len < 0) {
        perror("Error in recvfrom");
        exit(1);
    }

    // 打印服务器回复
    buffer[recv_len] = '\0';
    printf("Received message from server: %s\n", buffer);

    // 关闭套接字
    close(client_socket);

    return 0;
}

这两个示例展示了UDP客户端和服务器的基本结构和用法。服务器监听指定端口并等待客户端发送的消息,而客户端发送消息到服务器并接收回复。请注意,UDP通信不保证数据的可靠性,因此在实际应用中需要根据需求进行数据丢失和错误处理。

总之,UDP是一种灵活且高效的协议,适用于需要快速数据传输和实时性的应用。在选择UDP时,应根据应用程序的需求和性质进行适当的决策。


http://www.niftyadmin.cn/n/5020515.html

相关文章

【数据结构】队列知识点总结--定义;基本操作;队列的顺序实现;链式存储;双端队列;循环队列

欢迎各位看官^_^ 目录 1.队列的定义 2.队列的基本操作 2.1初始化队列 2.2判断队列是否为空 2.3判断队列是否已满 2.4入队 2.5出队 2.6完整代码 3.队列的顺序实现 4.队列的链式存储 5.双端队列 6.循环队列 1.队列的定义 队列&#xff08;Queue&#xff09;是一种先…

YOLO 物体检测 系列教程 总目录

1、YOLO物体检测系列1&#xff1a;YOLOV1整体解读 YOLO物体检测系列1&#xff1a;YOLOV1整体解读 2、YOLO物体检测系列2&#xff1a;YOLOV2整体解读 YOLO物体检测系列2&#xff1a;YOLOV2整体解读

day-43 代码随想录算法训练营(19) 动态规划 part 05

1049.最后一块石头的重量||&#xff08;有点感觉了&#xff09; 分析&#xff1a; 只有石头不相等时&#xff0c;才会剩下石头&#xff0c;所以相等的部分会两两抵消&#xff1b;所以最后一块石头一定是两两抵消的结果&#xff0c;总和-抵消*2最后一块石头转换为背包问题&…

C语言 数据结构与算法 I

C语言-数据结构与算法 C语言基础 因为之前写算法都是用C&#xff0c;也有了些C基础&#xff0c;变量常量数据类型就跳过去吧。 首先是环境&#xff0c;学C时候用Clion&#xff0c;C语言也用它写吧~ 新建项目&#xff0c;选C执行文件&#xff0c;语言标准。。。就先默认C99吧…

day34 Set

概述 Set也是集合Collection接口的子接口 Set也是集合Collection接口的子接口 特点&#xff1a;不保证元素有顺序&#xff0c;数组元素不可以重复 HashSet: 底层是基于HashMap的。元素是无序的。元素不可重复&#xff0c;去重机制是依据hashCode()和equals()方法 LinkedHas…

docker 安装mysql

参考&#xff1a;mac-docker安装使用mysql - 码农教程 docker pull mysql/mysql-server docker run --name mysql01 -p 3306:3306 -e MYSQL_ROOT_PASSWORD123456 -d mysql/mysql-serverdocker exec -it mysql01 /bin/bash

Augmented Large Language Models with Parametric Knowledge Guiding

本文是LLM系列文章&#xff0c;针对《Augmented Large Language Models with Parametric Knowledge Guiding》的翻译。 参数知识引导下的增强大型语言模型 摘要1 引言2 相关工作3 LLM的参数化知识引导4 实验5 结论 摘要 大型语言模型&#xff08;LLM&#xff09;凭借其令人印…

HT for Web (Hightopo) 使用心得(1)- 基本概念

Hightopo 公司 3D 可视化产品有对应的官方手册。但是这些手册内容比较多。对于想学习的新同学来说可能相对比较繁琐。这里本人根据个人使用经验做了一些总结。希望对读者有所帮助。 本文会提到一些前端开发的概念&#xff0c;如 H5, JavaScript&#xff0c;JSON 等。没有开发经…