当前位置: 首页 > article >正文

基于C语言实现的UDP服务器

   

目录

一、UDP协议简介

二、基于C语言实现UDP服务器

1. 所需的头文件

2. 创建UDP服务器的核心代码

3. 代码解析

4. 编译和运行

5. 测试UDP服务器

6. 运行客户端

三、总结


     UDP(User Datagram Protocol,用户数据报协议)是一种无连接的传输层协议,适用于对实时性有较高要求的应用场景,如视频流传输、语音通信、在线游戏等。与TCP不同,UDP不保证数据的可靠性和顺序性,但其传输速度较快。

        本文将介绍如何使用C语言编写一个简单的UDP服务器程序,以及如何接收和处理客户端发送的数据。

一、UDP协议简介

UDP是一种面向无连接的传输层协议,具有以下几个特点:

  • 无连接:无需建立连接,数据可以直接发送给目标主机。
  • 不可靠性:UDP不保证数据包的顺序和到达,可能会丢失数据包。
  • 面向报文:以独立的报文形式发送数据,不像TCP那样需要维护流的状态。
  • 效率高:由于不需要连接建立和维护,UDP的传输效率较高。

二、基于C语言实现UDP服务器

        下面将演示如何使用C语言实现一个简单的UDP服务器,步骤包括创建套接字、绑定地址、接收数据和发送响应。

1. 所需的头文件

在C语言中实现网络编程,通常需要引入以下头文件:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>

2. 创建UDP服务器的核心代码

以下是一个简单的UDP服务器实现,它会监听指定端口并接收客户端发送的消息。

#define PORT 12345    // 服务器监听的端口号
#define BUFFER_SIZE 1024  // 缓冲区大小

int main() {
    int sockfd;
    char buffer[BUFFER_SIZE];
    struct sockaddr_in server_addr, client_addr;
    socklen_t addr_len;
    ssize_t n;

    // 创建UDP套接字
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        perror("创建套接字失败");
        exit(EXIT_FAILURE);
    }

    // 配置服务器地址
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET; // IPv4
    server_addr.sin_addr.s_addr = INADDR_ANY; // 接受任意IP地址
    server_addr.sin_port = htons(PORT); // 端口号转换为网络字节序

    // 绑定套接字到指定的IP地址和端口
    if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        perror("绑定失败");
        close(sockfd);
        exit(EXIT_FAILURE);
    }

    printf("UDP服务器已启动,正在监听端口 %d...\n", PORT);

    // 循环接收数据
    while (1) {
        addr_len = sizeof(client_addr);
        // 接收数据报
        n = recvfrom(sockfd, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&client_addr, &addr_len);
        if (n < 0) {
            perror("接收数据失败");
            continue;
        }

        buffer[n] = '\0'; // 确保字符串以'\0'结尾
        printf("接收到来自 %s:%d 的消息:%s\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), buffer);

        // 发送响应
        const char *response = "服务器已收到您的消息";
        sendto(sockfd, response, strlen(response), 0, (struct sockaddr *)&client_addr, addr_len);
    }

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

3. 代码解析

  • 创建UDP套接字socket(AF_INET, SOCK_DGRAM, 0)函数创建一个UDP套接字,其中AF_INET表示使用IPv4协议,SOCK_DGRAM表示使用UDP协议。
  • 绑定服务器地址和端口bind()函数用于将套接字绑定到本地地址和端口,这样服务器可以监听指定端口的请求。
  • 接收数据报recvfrom()函数用于接收来自客户端的数据,并获取发送方的地址信息。
  • 发送响应sendto()函数用于将数据发送回客户端,这里发送了一个简单的响应消息。
  • 关闭套接字:服务器在程序退出前关闭套接字,以释放资源。

4. 编译和运行

可以使用以下命令编译和运行上述代码:

gcc -o udp_server udp_server.c
./udp_server

运行后,服务器将开始监听端口12345,等待接收客户端的消息。

5. 测试UDP服务器

为了测试服务器的功能,我们可以使用以下简单的UDP客户端代码来发送消息:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>

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

int main() {
    int sockfd;
    struct sockaddr_in server_addr;
    char buffer[BUFFER_SIZE];
    socklen_t addr_len;

    // 创建UDP套接字
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        perror("创建套接字失败");
        exit(EXIT_FAILURE);
    }

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

    // 发送消息到服务器
    const char *message = "Hello, UDP Server!";
    sendto(sockfd, message, strlen(message), 0, (struct sockaddr *)&server_addr, sizeof(server_addr));

    // 接收服务器的响应
    addr_len = sizeof(server_addr);
    ssize_t n = recvfrom(sockfd, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&server_addr, &addr_len);
    if (n > 0) {
        buffer[n] = '\0';
        printf("服务器响应:%s\n", buffer);
    }

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

6. 运行客户端

编译并运行客户端程序,可以发送消息到服务器并接收服务器的响应。

gcc -o udp_client udp_client.c
./udp_client

三、总结

        本文介绍了如何使用C语言实现一个简单的UDP服务器,以及客户端如何与之通信。通过该示例代码,可以理解UDP协议的基本操作步骤和使用场景。UDP适用于对传输速度和实时性要求较高的场景,但在实际应用中,需考虑其不可靠性,可能需要添加额外的机制来保证数据传输的可靠性。


http://www.kler.cn/a/371598.html

相关文章:

  • HTML练习题:彼岸的花(web)
  • 「C/C++」C++ 设计模式 之 单例模式(Singleton)
  • 配置系统使用
  • 华为手机卸载系统应用的方法
  • CheckPointUtilsTest
  • 通俗直观介绍ChatGPT背后的大语言模型理论知识
  • Spring Boot 经典九设计模式全览
  • Linux 命令行参数 环境变量
  • 自己动手给ESP8285 / ESP8266 1MB 编译新版AT 固件
  • 第二代支付系统报文交换标准【大额支付系统分册】(版本1.5.6)
  • 【笔记】复数基础复数相乘的物理意义:旋转+缩放
  • synchronized基本用法、原理?
  • 论文阅读 - Pre-trained Online Contrastive Learning for Insurance Fraud Detection
  • es实现自动补全
  • k8s_Pod健康检查
  • Mamba应用领域
  • 【C++】踏上C++学习之旅(四):细说“内联函数“的那些事
  • 如何实现PHP的安全最大化
  • ETF申购赎回指南:详解注意事项与低费率券商推荐!
  • 双十一我都入手了啥大件?这几款超值好物分享给你
  • c++习题36-奇数单增序列
  • 【17】 傅立叶分析
  • Java项目实战II基于Spring Boot的小型诊疗预约平台(开发文档+数据库+源码)
  • 【LeetCode热题100】链表
  • 初识算法 · 前缀和(1)
  • 使用TimeShift备份和恢复Ubuntu Linux