Linux网络编程之UDP Socket程序示例

下面是关于使用UDP Socket进行Linux网络编程的攻略及示例.

UDP Socket编程简介

UDP全称User Datagram Protocol,是一种无连接的,不可靠的面向数据报的传输协议,采用UDP传输需要自行保证数据的可靠性和完整性。因为UDP通信无连接,所以它发送的数据报文既不需要建立连接,也不需要断开连接,数据报文也不需要发送端和接收端建立逻辑连接,数据报文在发送端产生,并被数据报文接收端所直接使用,每个数据报文的大小限制为64k。

在Linux环境下,UDP Socket编程广泛应用于基于网络的服务端和客户端应用程序,包括网络通信、远程验证和数据采集等领域。

UDP Socket程序示例1

下面我们以简单的基于UDP Socket的回声服务端和客户端作为示例,来了解如何使用UDP Socket进行Linux网络编程。

回声服务端程序

服务端程序负责收到客户端发送的消息后,通过发送一条同样的消息进行“回声”。

// UDP Echo Server Program
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>

#define BUF_SIZE 65536

int main(int argc, char **argv) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <port>\n", argv[0]);
        exit(1);
    }
    // 创建一个UDP Socket
    int serv_sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (serv_sock == -1) {
        fprintf(stderr, "create socket error: %s", strerror(errno));
        exit(1);
    }
    // 构建本地地址
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;    // 使用IPv4
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);    // 使用任意可用的IP地址
    serv_addr.sin_port = htons(atoi(argv[1]));    // 获取命令行参数指定的端口号
    // 绑定监听套接字
    if (bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1) {
        fprintf(stderr, "bind socket error: %s", strerror(errno));
        close(serv_sock);
        exit(1);
    }
    printf("UDP Echo Service started at %d.\n", atoi(argv[1]));
    // 接收客户端请求并回声相同消息
    while (true) {
        struct sockaddr_in client_addr;
        socklen_t client_addr_len = sizeof(client_addr);
        char buf[BUF_SIZE];
        memset(&buf, 0, BUF_SIZE);
        ssize_t recv_len = recvfrom(serv_sock, buf, BUF_SIZE, 0, (struct sockaddr*)&client_addr, &client_addr_len);
        printf("Client %s:%d request: %s", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), buf);
        ssize_t echo_len = sendto(serv_sock, buf, recv_len, 0, (struct sockaddr*)&client_addr, client_addr_len);
        printf("Response %d bytes to %s:%d.\n", echo_len, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
    }
    close(serv_sock);
    return 0;
}

回声客户端程序

客户端程序主要负责向服务端发送一条消息,并接收服务端的回声消息。

// UDP Echo Client Program
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>

#define BUF_SIZE 65536

int main(int argc, char **argv) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <ip> <port>\n", argv[0]);
        exit(1);
    }
    // 构建服务端地址
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;    // 使用IPv4
    serv_addr.sin_addr.s_addr = inet_addr(argv[1]);    // 获取命令行参数指定的服务端IP地址
    serv_addr.sin_port = htons(atoi(argv[2]));    // 获取命令行参数指定的服务端端口号
    // 创建UDP Socket
    int client_sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (client_sock == -1) {
        fprintf(stderr, "create socket error: %s", strerror(errno));
        exit(1);
    }
    while (true) {
        char buf[BUF_SIZE];
        memset(&buf, 0, BUF_SIZE);
        printf("Enter message to send: ");
        fgets(buf, BUF_SIZE, stdin);
        ssize_t send_len = sendto(client_sock, buf, strlen(buf), 0, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
        if (send_len == -1) {
            fprintf(stderr, "send message error: %s", strerror(errno));
        } else {
            ssize_t resp_len = recv(client_sock, buf, BUF_SIZE, 0);
            if (resp_len == -1) {
                fprintf(stderr, "receive response error: %s", strerror(errno));
            } else {
                printf("Echo message from %s:%d: %s", inet_ntoa(serv_addr.sin_addr), ntohs(serv_addr.sin_port), buf);
            }
        }
    }
    close(client_sock);
    return 0;
}

UDP Socket程序示例2

下面我们以基于UDP Socket的广播客户端程序作为示例,来了解如何使用UDP Socket进行Linux网络编程。

广播客户端程序

广播客户端程序主要负责向本地网络内的所有主机广播一条UDP消息。

// UDP Broadcast Client Program
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>

#define BUF_SIZE 65536

int main(int argc, char **argv) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <ip> <port>\n", argv[0]);
        exit(1);
    }
    // 创建UDP Socket
    int client_sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (client_sock == -1) {
        fprintf(stderr, "create socket error: %s", strerror(errno));
        exit(1);
    }
    // 设置广播属性,并绑定本地地址到Socket上
    int enable_broadcast = 1;
    if (setsockopt(client_sock, SOL_SOCKET, SO_BROADCAST, &enable_broadcast, sizeof(enable_broadcast)) == -1) {
        fprintf(stderr, "setsockopt error: %s", strerror(errno));
        exit(1);
    }
    struct sockaddr_in local_addr;
    memset(&local_addr, 0, sizeof(local_addr));
    local_addr.sin_family = AF_INET;    // 使用IPv4
    local_addr.sin_addr.s_addr = INADDR_ANY;    // 使用任意IP地址
    local_addr.sin_port = 0;    // 自动分配一个空闲端口
    if (bind(client_sock, (struct sockaddr*)&local_addr, sizeof(local_addr)) == -1) {
        fprintf(stderr, "bind socket error: %s", strerror(errno));
        close(client_sock);
        exit(1);
    }
    // 构建目标地址
    struct sockaddr_in dest_addr;
    memset(&dest_addr, 0, sizeof(dest_addr));
    dest_addr.sin_family = AF_INET;    // 使用IPv4
    dest_addr.sin_addr.s_addr = inet_addr(argv[1]);    // 获取命令行参数指定的目标IP地址
    dest_addr.sin_port = htons(atoi(argv[2]));    // 获取命令行参数指定的目标端口号
    // 使用广播地址发送消息
    while (true) {
        char buf[BUF_SIZE];
        memset(&buf, 0, BUF_SIZE);
        printf("Enter message to broadcast: ");
        fgets(buf, BUF_SIZE, stdin);
        ssize_t send_len = sendto(client_sock, buf, strlen(buf), 0, (struct sockaddr*)&dest_addr, sizeof(dest_addr));
        if (send_len == -1) {
            fprintf(stderr, "send message error: %s", strerror(errno));
        } else {
            printf("Broadcast message to %s:%d successful.", inet_ntoa(dest_addr.sin_addr), ntohs(dest_addr.sin_port));
        }
    }
    close(client_sock);
    return 0;
}

以上是使用UDP Socket进行Linux网络编程的攻略及两个示例。希望这篇攻略对你在Linux网络编程方面有所帮助!

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Linux网络编程之UDP Socket程序示例 - Python技术站

(0)
上一篇 2023年5月30日
下一篇 2023年5月30日

相关文章

  • C 程序 查找数组元素的总和

    C程序 查找数组元素的总和 简介 本程序通过输入一个包含n个数的整型数组,求出数组中所有元素的总和。 使用攻略 编译环境 本程序使用C语言编写,建议使用gcc编译器,在Linux环境下执行。 输入数组 程序使用scanf函数从标准输入中读入数组元素,用户需输入n个整型数值,以空格或换行符分隔。 示例输入: 5 1 2 3 4 5 程序设计 本程序使用for循…

    C 2023年5月9日
    00
  • 详解C语言结构体,枚举,联合体的使用

    详解C语言结构体、枚举、联合体的使用 C语言的结构体、枚举、联合体是三种比较重要的数据类型,可以在程序中方便地实现复杂的数据结构和算法。本文将从基本概念入手,详细介绍它们的定义、初始化、访问、应用等方面,帮助读者深入理解它们的使用方法。 结构体 定义 结构体是由若干个不同类型的数据成员组合而成的一个数据类型,可以表示一个具有复杂内部结构的数据。结构体由 st…

    C 2023年5月22日
    00
  • C语言程序设计50例(经典收藏)

    “C语言程序设计50例(经典收藏)”是一本经典的编程书籍,旨在通过50个经典的C语言程序设计例子,让读者提高编程水平。本书包含了基础及进阶语言知识和常用数据结构的实现等内容,是提高编程技能的好教材。 以下是该书的完整攻略: 一、书籍概述 “C语言程序设计50例(经典收藏)”是一本C语言编程经典书籍,一共有50个程序例子,每个例子都对应着一种编程思路,适合初学…

    C 2023年5月23日
    00
  • C++使用递归和非递归算法实现的二叉树叶子节点个数计算方法

    C++使用递归和非递归算法实现的二叉树叶子节点个数计算方法 计算一个二叉树中叶子节点的个数是二叉树的常见问题之一。使用递归或非递归算法都可以实现这个功能,下面我们逐步讲解两种算法的实现过程。 递归算法 递归算法是一种自上而下、分而治之的算法思想。在二叉树中,递归算法的实现也是先计算根节点,再计算左子树和右子树,最终得出结果。 递归计算二叉树叶子节点个数的方法…

    C 2023年5月23日
    00
  • python Yaml、Json、Dict之间的转化

    现在我们来详细讲解Python中Yaml、Json和Dict之间的相互转化。 Yaml、Json和Dict的介绍 Yaml是一种轻量级的用于描述数据序列化的格式,读起来比较易懂,常用于配置文件和数据交换格式。 Json是JavaScript对象表示法,是另一种数据交换格式,通常用于Web应用程序。 Dict是Python中的一种内置数据类型,表示键值对之间的…

    C 2023年5月23日
    00
  • C语言实现财务管理系统

    C语言实现财务管理系统攻略 1. 系统概述 本系统采用C语言编写,实现了简单的财务管理功能,包括记账、查账、统计等功能,适合个人和小型企业使用。 2. 系统设计 系统包括以下几个模块: 用户登录模块 用户登录时需要输入用户名和密码,系统会验证用户信息是否正确。如果验证通过,系统会将用户信息保存到全局变量中。 记账模块 用户可以输入收支的详细信息,包括日期、类…

    C 2023年5月23日
    00
  • 在PHP语言中使用JSON和将json还原成数组的方法

    接下来我将详细讲解如何在PHP语言中使用JSON以及将JSON还原成数组的方法。 将数组转换成JSON字符串 在PHP中,可以使用json_encode()函数将数组转换成JSON字符串。该函数的语法如下: json_encode(mixed $value, int $options = 0, int $depth = 512): string|false …

    C 2023年5月23日
    00
  • C语言实现实验设备管理系统

    C语言实现实验设备管理系统 简介 C语言是一种面向过程的编程语言,广泛应用于系统软件、存储管理、操作系统、网络协议等领域。实验设备管理系统是一种重要的实验室管理工具,在实验室管理中得到广泛应用。本文将详细讲解如何使用C语言实现实验设备管理系统。 环境配置 在开始编写代码之前,需要先配置好C语言的开发环境。以下是环境配置的基本步骤: 安装C语言编译器,建议选择…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部