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日

相关文章

  • sqlmap之os shell图文详细解析

    让我来详细讲解“sqlmap之os shell图文详细解析”的完整攻略。 SQLMap之OS Shell图文详细解析 什么是SQLMap SQLMap是一个用于检测和利用SQL注入漏洞的开源工具,可以自动化地进行注入测试,并且提供了多种手段来发现和利用漏洞,是渗透测试中非常实用的工具之一。SQLMap完全基于Python开发,支持Linux和Windows操…

    C 2023年5月23日
    00
  • C 语言基础之C语言的常见关键字

    关键字是C语言中预定义的具有特定含义的词汇,其用途及含义很多时候需要根据上下文来理解。本文将介绍C语言中常见的关键字及其作用。 关键字概述 C语言中的关键字共有32个,这32个关键字都是预定义的,不能重新定义或者重载。以下是这32个关键字的完整列表。 auto, break, case, char, const, continue, default, do,…

    C 2023年5月24日
    00
  • 真三国无双7:猛将传关银屏C技怎么追加攻击? 关银屏C技追加攻击方法介绍

    OK,让我为您详细讲解“真三国无双7:猛将传关银屏C技怎么追加攻击?关银屏C技追加攻击方法介绍”的完整攻略。 猛将传关银屏C技的追加攻击 首先,我们需要知道什么是“C技追加攻击”。在真三国无双7中,每个武将都有自己的C技能,在使用C技能的时候,可以通过按下Attack按钮来进行追加攻击,有些武将的追加攻击可以造成更高的伤害,关银屏就是其中之一。 关银屏的C技…

    C 2023年5月23日
    00
  • 比特币原理是什么?比特币原理详解

    比特币原理是什么? 比特币(Bitcoin)是一种去中心化的数字货币,是基于点对点网络技术和密码学算法实现的。它的核心原领是区块链技术,是一种分布式账本技术,使得比特币能够实现去中心化、防篡改。 比特币采用共识机制来保证交易的安全和可靠性。它没有中心化的发行机构,每一笔交易都被记录到区块链上。同时,比特币的发行数量是有限的,最大发行量不超过2100万枚。 比…

    C 2023年5月22日
    00
  • 一篇文章带你入门C++的异常处理

    一篇文章带你入门C++的异常处理 异常处理介绍 C++中有很多异常,比如说:除0异常、数组越界异常等。程序在执行中如果遇到异常,如果没有处理,将会导致程序崩溃。为了应对这种情况,我们可以使用C++的异常处理机制。 C++的异常处理机制的基本结构如下: try { // 可能会产生异常的代码 } catch(Exception e) { // 异常处理 } t…

    C 2023年5月22日
    00
  • 详解编译器编译原理

    下面是详解编译器编译原理的完整攻略。 什么是编译器? 编译器是一种将源代码转换为目标代码的程序。源代码可以是任何一种高级语言,例如C、C++、Java等等,而目标代码则是汇编语言或机器语言。编译器有很多种,常见的有GCC、Clang等。 编译器的基本流程 编译器的基本流程分为三个阶段:词法分析、语法分析和代码生成。 1. 词法分析 词法分析阶段将源代码分解成…

    C 2023年5月23日
    00
  • 浅谈C语言的字节对齐 #pragma pack(n)2

    浅谈C语言的字节对齐 在C语言中,结构体是将不同类型的数据存储在一起的一种基本数据类型。在结构体中,结构体成员所占用的内存空间是按照类型大小和字节对齐规则来确定的。字节对齐是计算机领域中的一个重要话题,本文将深入浅出地讲解C语言的字节对齐。 定义 字节对齐指的是将数据存储在内存中时,按照一定的规则将数据的起始位置往后挪动若干字节,使得成员变量对齐到特定的地址…

    C 2023年5月23日
    00
  • 逍遥自在学C语言 | 位运算符>>的高级用法

    前言 在上一篇文章中,我们介绍了<<运算符的高级用法,本篇文章,我们将介绍>> 运算符的一些高级用法。 一、人物简介 第一位闪亮登场,有请今后会一直教我们C语言的老师 —— 自在。 第二位上场的是和我们一起学习的小白程序猿 —— 逍遥。 二、优化除法运算 除法运算需要比位移运算需要更多的计算资源,某些情况下采用位移运算可以提高性能 代…

    C语言 2023年4月17日
    00
合作推广
合作推广
分享本页
返回顶部