百问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)…...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...
