百问FB网络编程 - UDP编程简单示例
6.5 UDP编程简单示例
UDP服务器首先进行初始化操作:调用函数socket创建一个数据报类型的套接字,函数bind将这个套接字与服务器的公认地址绑定在一起。然后调用函数recvfrom接收UDP客户机的数据报。UDP客户机首先调用函数socket创建一个数据报套接字,然后调用函数sendto向服务器发送数据报。在结束通信后,客户机调用close关闭UDP套接字,服务器继续使用这个UDP套接字接收其它客户机的数据报。
6.5.1 服务器端代码
参考UDP/server_line.c
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4//#include <sys/type.h>
5#include <sys/socket.h>
6#include <netinet/in.h>
7#include <arpa/inet.h>
8#include <unistd.h>
9#include <signal.h>
10
11/*服务器端口为8180*/
12#define SERVER_PORT 8180
13
14/************************************************************
15*函数功能描述:从8180端口接收客户端数据
16*输入参数:无
17*输出参数:打印客户IP以及发来的信息
18*返回值:无
19*修改日期 版本号 修改人 修改内容
20*2020/05/13 v1.0.0 zonghzha creat
21*************************************************************/
22
23
24int main(int argc, char **argv)
25{
26 unsigned char buf[512];
27 int len;
28 int duty_socket;
29 int customer_socket;
30 struct sockaddr_in socket_server_addr;
31 struct sockaddr_in socket_client_addr;
32 int ret;
33 int addr_len;
34
35 /* 创建数据报套接字 */
36 duty_socket = socket(AF_INET, SOCK_DGRAM, 0);
37 if (duty_socket == -1)
38 {
39 printf("socket error");
40 return -1;
41 }
42
43 /* 服务器端填充 sockaddr_in结构 */
44 socket_server_addr.sin_family = AF_INET;
45 socket_server_addr.sin_port = htons(SERVER_PORT);
46 socket_server_addr.sin_addr.s_addr = INADDR_ANY;
47 memset(socket_server_addr.sin_zero, 0, 8);
48
49 /*绑定套接字*/
50 ret = bind(duty_socket, (const struct sockaddr *)&socket_server_addr, sizeof(struct sockaddr));
51 if (ret == -1)
52 {
53 printf("bind error!\n");
54 return -1;
55 }
56
57
58 while (1)
59 {
60 addr_len = sizeof(struct sockaddr);
61 /* 接收客户端数据报,返回的为接收到的字节数 */
62 len = recvfrom(duty_socket, buf, sizeof(buf), 0, (struct sockaddr *)&socket_client_addr, &addr_len);
63 if (len > 0)
64 {
65 buf[len] = '\0';
66 printf("Get Msg from %s : %s\n", inet_ntoa(socket_client_addr.sin_addr), buf);
67 }
68
69 }
70
71 close(duty_socket);
72 return 0;
73}
74
6.5.2 客户端代码
6.5.2.1 客户端程序1
参考UDP/client_line_1.c
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <sys/socket.h>
5#include <netinet/in.h>
6#include <arpa/inet.h>
7#include <unistd.h>
8
9#define SERVER_PORT 8180
10
11/************************************************************
12*函数功能描述:向指定IP的8180端口发送数据
13*输入参数:点分十进制服务器IP
14*输出参数:无
15*返回值:无
16*修改日期 版本号 修改人 修改内容
17*2020/05/13 v1.0.0 zonghzha creat
18*************************************************************/
19
20int main(int argc, char **argv)
21{
22 unsigned char buf[512];
23 int len;
24 struct sockaddr_in socket_server_addr;
25 int ret;
26 int addr_len;
27 int client_socket;
28
29
30 if (argc != 2)
31 {
32 printf("Usage:\n");
33 printf("%s <server_ip>\n", argv[0]);
34 return -1;
35 }
36
37 /*创建套接字*/
38 client_socket = socket(AF_INET, SOCK_DGRAM, 0);
39 if (client_socket == -1)
40 {
41 printf("socket error");
42 return -1;
43 }
44
45 /* 填充服务端的资料 */
46 socket_server_addr.sin_family = AF_INET;
47 socket_server_addr.sin_port = htons(SERVER_PORT);
48 if (inet_aton(argv[1], &socket_server_addr.sin_addr) == 0)
49 {
50 printf("invalid server ip\n");
51 return -1;
52 }
53 memset(socket_server_addr.sin_zero, 0, 8);
54
55
56
57
58 while (1)
59 {
60 if (fgets(buf, sizeof(buf), stdin))
61 {
62 // len = send(client_socket, buf, strlen(buf), 0);
63 /*向服务器端发送数据报*/
64 addr_len = sizeof(struct sockaddr);
65 len = sendto(client_socket, buf, sizeof(buf), 0, (struct sockaddr *)&socket_server_addr, addr_len);
66 if (len <= 0)
67 {
68 close(client_socket);
69 return -1;
70 }
71 }
72 }
73
74 close(client_socket);
75 return 0;
76}
77
问:用UDP协议写网络通讯程序不可以用connect函数吗?
答:非也。
6.5.2.2 客户端程序2
参考UDP/client_line_2.c
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <sys/socket.h>
5#include <netinet/in.h>
6#include <arpa/inet.h>
7#include <unistd.h>
8
9/*服务器端口为8180*/
10#define SERVER_PORT 8180
11
12/************************************************************
13*函数功能描述:向指定IP的8180端口发送数据
14*输入参数:点分十进制服务器IP
15*输出参数:无
16*返回值:无
17*修改日期 版本号 修改人 修改内容
18*2020/05/13 v1.0.0 zonghzha creat
19*************************************************************/
20
21int main(int argc, char **argv)
22{
23 unsigned char buf[512];
24 int len;
25 struct sockaddr_in socket_server_addr;
26 int ret;
27 int addr_len;
28 int client_socket;
29
30
31 if (argc != 2)
32 {
33 printf("Usage:\n");
34 printf("%s <server_ip>\n", argv[0]);
35 return -1;
36 }
37
38 /*创建数据报套接字*/
39 client_socket = socket(AF_INET, SOCK_DGRAM, 0);
40 if (client_socket == -1)
41 {
42 printf("socket error");
43 return -1;
44 }
45
46 socket_server_addr.sin_family = AF_INET;
47 socket_server_addr.sin_port = htons(SERVER_PORT);
48 if (inet_aton(argv[1], &socket_server_addr.sin_addr) == 0)
49 {
50 printf("invalid server ip\n");
51 return -1;
52 }
53 memset(socket_server_addr.sin_zero, 0, 8);
54
55 ret = connect(client_socket, (const struct sockaddr *)&socket_server_addr, sizeof(struct sockaddr));
56 if (ret == -1)
57 {
58 printf("connect error!\n");
59 return -1;
60 }
61
62
63 while (1)
64 {
65 if (fgets(buf, sizeof(buf), stdin))
66 {
67 len = send(client_socket, buf, strlen(buf), 0);
68 if (len <= 0)
69 {
70 close(client_socket);
71 return -1;
72 }
73 }
74 }
75
76 close(client_socket);
77 return 0;
78}
79
在客户端代码2中,connect函数并非真的在协议层建立了连接,它只是指定了服务器的地址和端口号信息。
因为在connect中指定了服务器的地址和端口号信息,所以后面的send就可以直接发送了,而不用再次指定地址和端口号。
6.5.3 Makefile文件
all:server client_1 client_2
server:server.cgcc $^ -o $@
client_1:client_1.cgcc $^ -o $@
client_2:client_2.cgcc $^ -o $@
clean:rm server client_1 client_2 -f(注意:命令语句的开头要用“Tab”键。)
6.5.4 执行
服务器端执行:
./server
客户端执行:
./client_1 127.0.0.1
客户端输入:
good night
服务器端显示:
Get Msg from 127.0.0.1 : good night
相关文章:
百问FB网络编程 - UDP编程简单示例
6.5 UDP编程简单示例 UDP服务器首先进行初始化操作:调用函数socket创建一个数据报类型的套接字,函数bind将这个套接字与服务器的公认地址绑定在一起。然后调用函数recvfrom接收UDP客户机的数据报。UDP客户机首先调用函数socket创建一个数据报套接字&…...
面试题:什么是ThreadLocal,如何实现的?
强烈推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站:人工智能 你是否还在为简历无人阅读而感到沮丧?是否因为寻觅不到理想的工作机会而感到焦虑不安?试试:看看…...
js后端开发之Next.js、Nuxt.js 与 Express.js
后端js之Next.js、Nuxt.js 与 Express.js 在现代 Web 开发中,JavaScript 已经成为前后端通用的编程语言,而选择合适的后端框架则是构建高效、可扩展应用程序的关键。本文将带你深入了解三个流行的 JavaScript 后端框架:Next.js、Nuxt.js 和 …...
飞牛Nas如何实现阿里云盘、百度网盘的资料迁移!
文章目录 📖 介绍 📖🏡 演示环境 🏡📒 如何使用飞牛NAS实现阿里云盘与百度网盘的数据互相迁移 📒📝 操作步骤注意事项⚓️ 相关链接 ⚓️📖 介绍 📖 你是否有将百度网盘的文件迁移到阿里云盘,或是将阿里云盘的资料转移到百度网盘的需求?本文将给大家演示如…...
如何在小米平板5上运行 deepin 23 ?
deepin 23 加入了 ARM64 支持,这里尝试将 deepin 系统刷入平板中,平常使用中,带个笔记本电脑有时候也会嫌比较麻烦,把 Linux 系统刷入平板中既满足了使用需要,又满足了轻便的需求。为什么不使用 Termux ?虽…...
【PlantUML系列】流程图(四)
目录 目录 一、基础用法 1.1 开始和结束 1.2 操作步骤 1.3 条件判断 1.4 并行处理 1.5 循环 1.6 分区 1.7 泳道 一、基础用法 1.1 开始和结束 开始一般使用start关键字;结束一般使用stop/end关键字。基础用法包括: start ... stopstart ...…...
操作系统:进程、线程与作业
背景介绍: 因为单道程序处理器效率低 、设备利用率低 、内存利用率低的问题人们提出了多道程序设计来解决这个问题。 多道程序致力于提高处理机、设备、内存等各种资源的利用率,从而提高系统效率,也就是吞吐量,吞吐量定义为单位时…...
先验地图--slam学习笔记
先验信息 (Prior Information) 先验信息指的是在收集新数据之前已有的知识或假设。这种信息可以来自之前的实验、历史数据、理论模型或专家意见。 地图信息:在无人驾驶中,车辆通常会预先加载高精度地图数据,这些地图数据提供了道路布局、车…...
空指针异常:软件开发中的隐形陷阱
在软件开发的世界里,bug如同隐藏在代码森林中的小怪兽,不时跳出来给开发者们制造惊喜(或惊吓)。其中,空指针异常(Null Pointer Exception, NPE)无疑是最令人头疼的一类。它悄无声息,…...
【Java从入门到放弃 之 GC】
垃圾回收 垃圾回收什么是垃圾引用计数法可达性分析算法 垃圾回收算法标记清除法标记复制法标记整理法分代 常用的垃圾回收器 垃圾回收 如果你学过C,你肯定知道,我们没申请一块内存,都要自己写回收内存的方法。而Java不需要我们管理内存&…...
【C++】等差数列末项计算题解析及优化
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯题目描述与输入输出要求💯数学分析与公式推导公差的计算通项公式推导 💯示例解析解题步骤 💯程序实现与解析初版代码代码解析优点与不足…...
vue中父组件接收子组件的多个参数的方法:$emit或事件总线
方法一:使用 $emit 方法 原理 子组件通过 $emit 方法向父组件发送事件,同时可以传递多个参数,父组件通过事件监听来接收这些参数。 示例 子组件代码 <template><div><button click"sendData">发送数据</…...
2024.12.10——攻防世界Web_php_include
知识点:代码审计 文件包含 伪协议 伪协议知识点补充: 在PHP中,伪协议(Pseudo Protocols)也被称为流包装器,这些伪协议以 php://开头,后面跟着一些参数,用于指定要执行的操作或需要…...
【机器学习算法】——数据可视化
1. 饼图:显示基本比例关系 import matplotlib.pyplot as pltplt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False# ——————————————————————————————————————————————————————…...
如何在 Android 项目中实现跨库传值
背景介绍 在一个复杂的 Android 项目中,我们通常会有多个库(lib),而主应用程序(app)依赖所有这些库。目前遇到的问题是,在这些库中,libAd 需要获取 libVip 的 VIP 等级状态…...
JavaCV之FFmpegFrameFilter视频转灰度
1、代码 package com.example.demo.ffpemg;import lombok.SneakyThrows; import org.bytedeco.javacv.*;public class FFmpegFrameFilterVideoExample {SneakyThrowspublic static void main(String[] args) {// 输入视频文件路径String inputVideoPath "f:/2222.mp4&qu…...
Redis:基于PubSub(发布/订阅)、Stream流实现消息队列
Redis - PubSub、Stream流 文章目录 Redis - PubSub、Stream流1.基于List的消息队列2.基于PubSub的消息队列3.基于Stream的消息队列1.Redis Streams简介2.Redis Streams基本命令1.XADD 添加消息到末尾2.XLEN 获取消息长度3.XREAD 读取消息 (单消费模式)4…...
C#飞行棋(新手简洁版)
我们要在主函数的顶部写一些全局静态字段 确保能在后续的静态方法中能够获取到这些值和修改 static int[] Maps new int[100];static string[] PlayerName new string[2];static int[] PlayerScore new int[2];static bool[] Flags new bool[2] {true,true }; static int[]…...
【OpenCV】图像转换
理论 傅立叶变换用于分析各种滤波器的频率特性。对于图像,使用 2D离散傅里叶变换(DFT) 查找频域。快速算法称为 快速傅立叶变换(FFT) 用于计算DFT。 Numpy中的傅立叶变换 首先,我们将看到如何使用Numpy查…...
力扣 重排链表-143
重排链表-143 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x), next(next)…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...
论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...
MyBatis中关于缓存的理解
MyBatis缓存 MyBatis系统当中默认定义两级缓存:一级缓存、二级缓存 默认情况下,只有一级缓存开启(sqlSession级别的缓存)二级缓存需要手动开启配置,需要局域namespace级别的缓存 一级缓存(本地缓存&#…...
