C语言实现UDP通信

下面是C语言实现UDP通信的完整攻略。

1. 确定需要使用的库和头文件

首先需要引入的头文件有:

#include <stdio.h>      //标准输入输出库
#include <stdlib.h>     //标准库
#include <string.h>     //字符串处理库
#include <unistd.h>     //Unix标准函数库
#include <sys/types.h>  //Unix/Linux系统基本类型定义
#include <sys/socket.h> //套接字函数库
#include <netinet/in.h> //IP地址和端口号定义

2. 创建UDP套接字

在准备使用UDP套接字之前,需要先调用 socket() 方法创建一个套接字。该方法接受三个参数:

int socket(int domain, int type, int protocol);

其中:

  • domain:协议域(通常是 AF_INET,表示TCP/IP协议);
  • type:套接字类型(通常是 SOCK_DGRAM,表示UDP套接字);
  • protocol:协议类型,通常为 0,表示默认协议。

创建UDP套接字的代码示例如下:

int sockfd = socket(AF_INET, SOCK_DGRAM, 0);

3. 套接字绑定地址和端口号

在创建UDP套接字后,需要将其绑定到一个本地地址和端口号上,以便于其他进程能够发送数据到该端口。可使用 bind() 方法进行绑定,该方法接受两个参数:

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

其中:

  • sockfd:创建好的套接字;
  • addr:要绑定的地址和端口号;
  • addrlen:地址和端口号的长度。

代码示例如下:

struct sockaddr_in addr;
addr.sin_family = AF_INET;              //协议域
addr.sin_port = htons(PORT);            //端口号
addr.sin_addr.s_addr = htonl(INADDR_ANY);//IP地址(在本机的任何一个IP上都能够接收到信息)

if(bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) == -1) {
    printf("Bind Error.\n");
    return 0;
}

4. 发送UDP数据

在UDP通信中,发送数据时使用 sendto()方法。该方法接受四个参数:

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);

其中:

  • sockfd:创建好的套接字;
  • buf:发送的数据内容;
  • len:发送的数据长度;
  • flags:调用操作方式,通常为 0
  • dest_addr:目标地址和端口号;
  • addrlen:目标地址和端口号的长度。

代码示例如下:

char sendbuf[1024] = "hello, this is a message from client.";
int sendbytes = sendto(sockfd, sendbuf, strlen(sendbuf), 0, (struct sockaddr *)&addr, sizeof(struct sockaddr));

5. 接收UDP数据

在UDP通信中,接收数据时使用 recvfrom() 方法。该方法接受五个参数:

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);

其中:

  • sockfd:创建好的套接字;
  • buf:接收到的数据内容;
  • len:接收数据的最大长度;
  • flags:调用操作方式,通常为 0
  • src_addr:发送方的地址和端口号;
  • addrlen:发送方的地址和端口号的长度。

代码示例如下:

char recvbuf[1024] = "";
struct sockaddr_in fromaddr;
socklen_t fromlen = sizeof(fromaddr);
int recvbytes = recvfrom(sockfd, recvbuf, 1024, 0, (struct sockaddr *)&fromaddr, &fromlen);
printf("Received message: %s\n", recvbuf);

示例说明

以下是一个简单的UDP客户端和服务器示例,可以直接运行在Linux上:

服务器

服务器会监听一个指定的端口,等待客户端发送信息。每当接收到客户端发来的信息时,会将消息打印出来,并向客户端回复一条信息。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define PORT 8888

int main(int argc, char *argv[]) {
    int sockfd;
    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        printf("Socket Error.\n");
        return 0;
    }

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;              //协议域
    addr.sin_port = htons(PORT);            //端口号
    addr.sin_addr.s_addr = htonl(INADDR_ANY);//IP地址(在本机的任何一个IP上都能够接收到信息)

    if(bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) == -1) {
        printf("Bind Error.\n");
        return 0;
    }
    printf("======Waiting for client's request======\n");

    char sendbuf[1024] = "";
    char recvbuf[1024] = "";
    struct sockaddr_in fromaddr;
    socklen_t fromlen = sizeof(fromaddr);
    while(1) {
        //receieve the message
        int recvbytes = recvfrom(sockfd, recvbuf, 1024, 0, (struct sockaddr *)&fromaddr, &fromlen);
        if(recvbytes == -1) {
            printf("Receive Error.\n");
            break;
        }
        recvbuf[recvbytes] = 0;

        char *client_ip = inet_ntoa(fromaddr.sin_addr);
        printf("[Received From %s:%u]> %s\n", client_ip, ntohs(fromaddr.sin_port), recvbuf);

        //send back to client
        sprintf(sendbuf, "Your message has been received.");
        int sendbytes = sendto(sockfd, sendbuf, strlen(sendbuf), 0, (struct sockaddr *)&fromaddr, fromlen);
        if(sendbytes == -1) {
            printf("Send Error.\n");
            break;
        }
    }

    close(sockfd);
    return 0;
}

客户端

客户端会向服务器发送一条信息,并等待服务器回复。当收到服务器的回复时,会将消息打印出来。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define PORT 8888

struct sockaddr_in addr;

int main(int argc, char *argv[]) {
    int sockfd;
    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        printf("Socket Error.\n");
        return 0;
    }

    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);

    char sendbuf[1024] = "hello, this is a message from client.";
    char recvbuf[1024] = "";
    int sendbytes = sendto(sockfd, sendbuf, strlen(sendbuf), 0, (struct sockaddr *)&addr, sizeof(struct sockaddr));
    if(sendbytes == -1) {
        printf("Send Error.\n");
        return 0;
    }

    int recvbytes = recvfrom(sockfd, recvbuf, 1024, 0, (struct sockaddr *)&addr, (socklen_t *)&sizeof(struct sockaddr));
    if(recvbytes == -1) {
        printf("Receive Error.\n");
        return 0;
    }
    recvbuf[recvbytes] = 0;

    printf("Receive: %s\n", recvbuf);

    close(sockfd);
    return 0;
}

这样,我们就成功地用C语言实现了UDP通信。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言实现UDP通信 - Python技术站

(1)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • C程序 将以英寸-英尺为单位的N个距离相加

    可以使用以下步骤完成C程序 将以英寸-英尺为单位的N个距离相加: 步骤一:定义距离变量和变量总数 首先需要定义变量来保存距离和距离总数,可以使用float类型来保存距离,int类型来保存距离总数,例如: int n; // 距离总数 float distance; // 单位为英尺或英寸的距离 步骤二:输入距离 使用循环结构来输入所有距离,例如: for(i…

    C 2023年5月9日
    00
  • C++设计模式之单例模式详解

    下面是详细讲解“C++设计模式之单例模式详解”的完整攻略。 什么是单例模式? 单例模式是一种创建型设计模式,用于确保类只有一个实例,并提供全局访问点。 为什么使用单例模式? 在某些情况下,我们需要确保在整个应用程序中只有一个实例化对象。单例模式使我们能够确保这一点。此外,单例模式还可以提供全局访问点,以便在应用程序中的任何地方都可以轻松访问单例对象。 实现单…

    C 2023年5月22日
    00
  • i9-10920Xc处理器怎么样 i9-10920Xc参数跑分性能评测

    i9-10920Xc处理器简介 i9-10920Xc是英特尔基于其Skylake-X微架构推出的一款高档桌面级处理器,主要面向需要高性能计算的用户,如游戏玩家、影音剪辑者、3D建模者等。i9-10920Xc处理器采用14nm工艺,拥有12个物理核心和24个线程,最高主频可达4.8 GHz。它的主要竞争对手是AMD Ryzen Threadripper 292…

    C 2023年5月23日
    00
  • iOS多线程应用开发中使用NSOperation类的基本方法

    iOS多线程应用开发中,使用NSOperation类可以有效地管理和控制多线程任务,提高应用程序的性能和响应速度。以下是使用NSOperation类的基本方法的完整攻略: 1. 概述 NSOperation是一个抽象类,定义了一个任务的基本接口,它是实现多线程编程的重要工具之一,可以继承NSOperation类来自定义任务,也可以使用NSBlockOpera…

    C 2023年5月22日
    00
  • VC程序设计小技巧20例

    “VC程序设计小技巧20例”完整攻略 简介 VC程序设计小技巧20例是VC++程序设计中常用的技巧总结,适合于从事VC++开发者,主要包括优化技巧、调试技巧、安全技巧等。以下是详细的攻略总结。 1. 使用switch代替if语句 if语句在判断多个变量时效率低下,可以使用switch代替,代码如下: char c; cin >> c; switc…

    C 2023年5月23日
    00
  • python转换wrf输出的数据为网页可视化json格式

    下面我将详细讲解如何使用Python将WRF模式输出的数据转换为可视化的JSON格式,让其可以在网页上进行展示。 步骤一:安装必要的Python库 首先,我们需要安装一些必要的Python库来进行数据处理和可视化。在这里我们使用以下Python库: netCDF4:一个用于读取和写入netCDF文件的Python库 numpy:一个用于科学计算的Python…

    C 2023年5月23日
    00
  • 深入浅出分析C++ string底层原理

    深入浅出分析C++ string底层原理 前言 在 C++ 中,string 类型是经常使用的字符串类型。了解 string 类的底层实现原理可以更好地理解其各种方法的行为,从而在编写程序时更加得心应手。本文将从以下几个方面对 string 类的底层实现进行说明: string 类的结构 string 类的构造函数 string 类的拷贝构造函数 strin…

    C 2023年5月23日
    00
  • C++11 并发指南之Lock 详解

    C++11 并发指南之 Lock 详解 什么是 Lock Lock 是一种同步机制,用于保护共享资源以避免并发访问。当多个线程访问同一个共享资源时,Lock 可以确保每个线程在使用共享资源时都是互斥的,从而避免竞态条件(Race Condition)和内存相关的不一致性问题。 Lock 的使用方法 C++11 中提供了两种 Lock 的实现方式:std::m…

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