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++中Boost的转换函数

    Boost库是一个为C++编程语言提供了许多扩展和增强功能的库。其中Boost库中的转换函数以简单的方式支持数字、字符串、日期和时间之间的转换。此处介绍Boost库转换函数的相关知识和应用。 Boost库的转换函数 Boost库提供了一些方便的转换函数,这些转换函数能够涉及到数字、字符串和时间等类型之间的转换。以下为一些常见的转换函数: lexical_ca…

    C 2023年5月23日
    00
  • C++实现单例模式的自动释放

    C++中的单例模式指的是某个类在整个程序中只有唯一的实例,这个实例可以全局被访问。而实现单例模式的自动释放则是让这个唯一实例在程序结束时自动释放,防止内存泄漏的发生。 以下是C++实现单例模式的自动释放的完整攻略: 懒汉式单例模式 实现思路 构造函数和析构函数私有化,防止实例对象被外部创建和销毁。 用静态指针变量指向唯一实例对象,保证实例对象的唯一性。 在程…

    C 2023年5月23日
    00
  • C语言多线程开发中死锁与读写锁问题详解

    C语言多线程开发中死锁与读写锁问题详解 介绍 多线程程序在共享资源的情况下容易产生各种问题。常见的问题之一是死锁和读写锁问题。本文将详细探讨这两个问题,并提供示例程序来阐述这些问题以及如何避免它们。读者需要有一定的C语言和多线程编程的基础知识。 死锁 当两个或多个线程同时尝试锁定一组资源,但是由于彼此依赖,从而导致其中一个线程等待的情况,这种情况叫做死锁。死…

    C 2023年5月23日
    00
  • 使用C语言实现CRC校验的方法

    使用C语言实现CRC校验的方法 什么是CRC校验 CRC(循环冗余校验)是一种根据网络数据包或电脑文件等数据产生简短固定位数校验码的一种信道编码技术,通常用于数据传输和存储检错。即在发送数据前按照预设的算法生成校验位,将该校验位附加在数据后传输,在接收方使用相同的算法和相同的数据来计算校验位,然后与接收到的校验位进行比较,以此判断接收数据是否正确。 CRC校…

    C 2023年5月23日
    00
  • c++ base64编解码使用示例

    C++ Base64编解码使用示例 简介 Base64是一种编码方式,能够将二进制数据转化为可打印的ASCII字符,常用于邮件、XML等文本转移过程中对二进制数据进行编码。C++也提供了Base64编解码的支持,这里就进行一下说明。 Base64编码 Base64编码将三个8位的字节转换为四个6位的字节,即每3个字节将会变成4个字节,更准确的说是每满4个字节…

    C 2023年5月30日
    00
  • C++类与对象的重点知识点详细分析

    C++类与对象的重点知识点详细分析 什么是C++类和对象? 类是一种用户自定义的数据类型,它将数据的成员变量和行为的成员函数封装到一个单元中,用以描述现实世界中的对象,从而方便程序员编写复杂的业务逻辑。类的实例化对象称为对象,每个对象都有自己的数据和操作方法。C++中的类和对象是C语言的扩展,可以使用封装、继承和多态等特性实现OOP思想。 如何定义一个C++…

    C 2023年5月22日
    00
  • C 和 Dart 的区别

    C 和 Dart 是两种不同的编程语言,它们各自有着不同的特点和用途。在这里,我将详细讲解 C 和 Dart 的区别及其使用攻略。 C 和 Dart 的基本介绍 C 语言 C 语言是一种广泛使用的高级程序设计语言,具有高效、简洁、快速和可移植等特点。C 语言可以用来开发操作系统、编写驱动程序、实现嵌入式系统和游戏引擎等需求。 Dart 语言 Dart 语言是…

    C 2023年5月10日
    00
  • C语言多维数组

    下面是“C语言多维数组”的完整使用攻略。 多维数组的定义与初始化 在C语言中,多维数组可以用来存储表格或矩阵等数据结构,它由一系列一维数组所组成,因此可以说,多维数组其实就是数组的数组。在定义多维数组时,需要确定它的维数和每一维的大小,例如: int arr[3][4]; //表示一个3行4列,总共12个元素的二维数组 也可以在定义同时初始化,例如: int…

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