【5】DongshanPI-Seven 应用开发_网络编程TCPUDP

news/2024/5/24 12:26:31/ 标签: 网络, tcp/ip, udp, Linux

目录

  • 1、网络编程概念
  • 2、网络编程的API
    • 2.1 网络通信交互示意图
    • 2.2 主要API
  • 3、编程测试
    • 3.1 TCP 测试
      • 3.1.1 server 程序
      • 3.1.2 Client 程序
      • 3.1.3 测试结果
    • 3.2 UDP 测试
      • 3.2.1 udp server
      • 3.2.2 udp client
      • 3.2.3 测试结果

1、网络编程概念

1.数据传输三要素:源、目的、长度。在网络传输中需要使用 IP+端口来表示源和目的。

2.网络传输中的两个对象:server 和 client

  • server:被动响应请求
  • client:主动发起请求

3.两种传输方式:TCP/UDP

  • TCP: 可靠传输
  • UDP:不可靠传输 (传输视频),无连接。

2、网络编程的API

2.1 网络通信交互示意图

1.TCP
在这里插入图片描述

2.UDP
在这里插入图片描述

2.2 主要API


1.创建1个套接字
int socket(int domain, int type, int protocol);
- domain:网络程序所在的主机采用的通信协议族。AF_INET
- type: 网络程序所采用的通信协议.SOCK_STREAM, TCP协议;SOCK_DGRAM,UDP协议。
- protocol:由于指定了type,此值设置为0
- 返回值: 成功,返回文件描述符;失败,返回-1.2.将本地的地址和端口同socket绑定
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
- sockfd:要绑定的套接字描述符
- addr:sockaddr 结构体指针,由于系统兼容性一般使用struct sockaddr_in来代替- struct sockaddr_in{unsigned short sin_family;   unsigned short sin_port;struct in_addr sin_addr;unsigned char sin_zero[8];}sin_family: AF_INETsin_port: 要监听的端口号sin_addr: INADDR_ANY,表示可以和任何的主机通信
- addrlen:sockaddr结构的长度
- 返回值:成功返回0;失败返回-13.启动监测数据
int listen(int sockfd,int backlog);
- sockfd:bind后的文件描述符;
- backlog:请求排队的最大长度。多个client连接时,可以接受的排队数量。
- 返回值:成功返回0;失败返回-14.接受一个连接
int accept(int sockfd, struct sockaddr *addr,int *addrlen);
- sockfd:listen后的文件描述符;
- addr、addrlen:给client程序填写的,server端只要传递指针即可。5. client向server发起一个连接
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
- sockfd:socket函数返回的文件描述符;
- addr:server端的地址和端口信息
- addrlen:sockaddr 的长度
- 返回值:成功返回0;失败返回-16. client/server 发送数据函数
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
- sockfd:套接字描述符
- buf:要发送数据缓冲区
- len:实际要发送的数据的字节数
- flags:一般设置为0
- 返回值:成功返回实际发送数据的字节数; 失败返回-17.client/server 接收数据函数
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
- sockfd:套接字描述符
- buf:用于存放接收数据的缓冲区
- len:buf长度
- flags:一般设置为0
- 返回值:成功返回实际接收数据的字节数; 失败返回-18.udp 接收函数
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
- sockfd:套接字描述符
- buf:用于存放接收数据的缓冲区
- len:buf长度
- flags:一般设置为0
- src_addr:源地址结构体
- addrlen:源地址结构体长度指针
- 返回值:成功返回实际接收数据的字节数; 失败返回-19.udp 发送函数
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
- sockfd:套接字描述符
- buf:用于存放接收数据的缓冲区
- len:buf长度
- flags:一般设置为0
- src_addr:源地址结构体
- addrlen:源地址结构体长度
- 返回值:成功返回实际发送数据的字节数; 失败返回-1

3、编程测试

3.1 TCP 测试

3.1.1 server 程序

server 程序有1个Client进程连接就创建一个进程。

#include <sys/types.h>			/* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>#define SERVER_PORT 1234
#define BACKLOG		10/* socket* bind* listen* accept* send/recv*/
int main( int argc, char **argv)
{int iSocketServer;int iSocketClient;int iRet;struct sockaddr_in tSocketServerAddr;struct sockaddr_in tSocketClientAddr;int iAddrLen;int iClientNum = -1;int iRecvLen;unsigned char RecvBuf[512];signal(SIGCHLD, SIG_IGN); // 处理client关闭后server僵尸进程iSocketServer = socket(AF_INET, SOCK_STREAM, 0);if(-1 == iSocketServer){printf("socket error!\r\n");return -1;}tSocketServerAddr.sin_family = AF_INET;tSocketServerAddr.sin_port = htons(SERVER_PORT);tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;memset(tSocketServerAddr.sin_zero, 0, 8);iRet = bind(iSocketServer, (const struct sockaddr *)&tSocketServerAddr,sizeof(struct sockaddr));if(-1 == iRet){printf("bind error!\r\n");return -1;}iRet = listen(iSocketServer, BACKLOG);if(-1 == iRet){printf("listen error!\r\n");return -1;}while(1){iSocketClient = accept(iSocketServer, (struct sockaddr *)&tSocketClientAddr, &iAddrLen);if(-1 != iSocketClient){iClientNum++;printf("Get connect from %d:%s\r\n", iClientNum, inet_ntoa(tSocketClientAddr.sin_addr)); // inet_ntoa缃戠粶鍦板潃杞崲鎴愬瓧绗︿覆if(!fork()){// 瀛愯繘绋嬩唬鐮?while(1){// 鎺ユ敹瀹㈡埛绔暟鎹苟鏄剧ずiRecvLen = recv(iSocketClient, RecvBuf, 511, 0);if(iRecvLen <= 0){printf("Recv error\n");close(iSocketClient);return -1;}else{RecvBuf[iRecvLen] = '\0';printf("Get Msg from client %d: %s\r\n", iClientNum, RecvBuf);}}}}}close(iSocketServer);return 0;
}

3.1.2 Client 程序

#include <sys/types.h>			/* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>#define SERVER_PORT 1234/* socket* connect * send/recv*/
int main( int argc, char **argv)
{int iSocketClient;int iRet;struct sockaddr_in tSocketServerAddr; unsigned char SendBuf[512];int iSendLen;if(argc != 2){printf("Usage:\n");printf("%s <server_ip>:\n",argv[0]);return -1;}iSocketClient = socket(AF_INET, SOCK_STREAM, 0);if(-1 == iSocketClient){printf("socket error!\r\n");return -1;}tSocketServerAddr.sin_family = AF_INET;tSocketServerAddr.sin_port = htons(SERVER_PORT);if(0 == inet_aton(argv[1], &tSocketServerAddr.sin_addr)){printf("invailed server ip!\r\n");return -1;}memset(tSocketServerAddr.sin_zero, 0, 8);iRet = connect(iSocketClient, (const struct sockaddr *)&tSocketServerAddr,sizeof(struct sockaddr));if(-1 == iRet){printf("connect error!\r\n");return -1;}while(1){if(fgets(SendBuf, 511, stdin)){iSendLen = send(iSocketClient, SendBuf, strlen(SendBuf), 0);if(iSendLen <= 0){printf("Recv error\n");close(iSocketClient);return -1;}}}
}

3.1.3 测试结果

1.client 1 连接server 发送数据
在这里插入图片描述
2.Client2 连接server发送数据在这里插入图片描述
3.server 接收数据
在这里插入图片描述
4.当关闭一个Client后,server没有僵尸进程
在这里插入图片描述

3.2 UDP 测试

udp_server_307">3.2.1 udp server

#include <sys/types.h>			/* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>#define SERVER_PORT 1234
#define BACKLOG		10/* socket* bind* sendto /recvfrom*/
int main( int argc, char **argv)
{int iSocketServer;int iSocketClient;int iRet;struct sockaddr_in tSocketServerAddr;struct sockaddr_in tSocketClientAddr;int iAddrLen;int iRecvLen;unsigned char RecvBuf[512];signal(SIGCHLD, SIG_IGN); iSocketServer = socket(AF_INET, SOCK_DGRAM, 0);if(-1 == iSocketServer){printf("socket error!\r\n");return -1;}tSocketServerAddr.sin_family = AF_INET;tSocketServerAddr.sin_port = htons(SERVER_PORT);tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;memset(tSocketServerAddr.sin_zero, 0, 8);iRet = bind(iSocketServer, (const struct sockaddr *)&tSocketServerAddr,sizeof(struct sockaddr));if(-1 == iRet){printf("bind error!\r\n");return -1;}while(1){iAddrLen = sizeof(struct sockaddr);iRecvLen = recvfrom(iSocketServer, RecvBuf, 511, 0, (struct sockaddr *)&tSocketClientAddr, &iAddrLen);if(iRecvLen > 0){RecvBuf[iRecvLen] = '\0';printf("Get Msg from client %s: %s\r\n", inet_ntoa(tSocketClientAddr.sin_addr), RecvBuf);}}close(iSocketServer);return 0;
}

udp_client_381">3.2.2 udp client

#include <sys/types.h>			/* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>#define SERVER_PORT 1234/* socket* sendto/recvfrom**/
int main( int argc, char **argv)
{int iSocketClient;int iRet;struct sockaddr_in tSocketServerAddr; unsigned char SendBuf[512];int iSendLen;int iAddrLen;if(argc != 2){printf("Usage:\n");printf("%s <server_ip>:\n",argv[0]);return -1;}iSocketClient = socket(AF_INET, SOCK_DGRAM, 0);if(-1 == iSocketClient){printf("socket error!\r\n");return -1;}tSocketServerAddr.sin_family = AF_INET;tSocketServerAddr.sin_port = htons(SERVER_PORT);if(0 == inet_aton(argv[1], &tSocketServerAddr.sin_addr)){printf("invailed server ip!\r\n");return -1;}memset(tSocketServerAddr.sin_zero, 0, 8);while(1){if(fgets(SendBuf, 511, stdin)){iAddrLen = sizeof(struct sockaddr);iSendLen = sendto(iSocketClient, SendBuf, strlen(SendBuf), 0,(const struct sockaddr *)&tSocketServerAddr, iAddrLen);if(iSendLen <= 0){printf("Recv error\n");close(iSocketClient);return -1;}}}
}

3.2.3 测试结果

1.udp client 1 发送数据
在这里插入图片描述
2.udp client2 发送数据
在这里插入图片描述
3.udp server 接收数据
在这里插入图片描述


To Be Continue …


http://www.ppmy.cn/news/1424490.html

相关文章

springCloud项目打包 ,maven package或install打包报错

解决思路一&#xff1a; <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.3.7.RELEASE</version></plugin><plugin>&…

【opencv】示例-videocapture_starter.cpp 从视频文件、图像序列或连接到计算机的摄像头中捕获帧...

/** * file videocapture_starter.cpp * brief 一个使用OpenCV的VideoCapture与捕获设备&#xff0c;视频文件或图像序列的入门示例 * 就像CV_PI一样简单&#xff0c;对吧&#xff1f; * * 创建于: 2010年11月23日 * 作者: Ethan Rublee * * 修改于: 2013年4月17日 * …

Python 选择用类或方法做装饰器的场景

在Python中,我们可以使用方法或者类来实现装饰器。选择使用方法还是类作为装饰器,主要取决于具体的应用场景。 使用方法作为装饰器 当装饰器的功能相对简单,不需要保持任何状态信息时,使用方法作为装饰器是一个不错的选择。这种情况下,装饰器通常只是对被装饰函数进行一些额外…

知了汇智鸿蒙系列讲座进校园,赋能产业数字化升级,助力创新人才培养

随着信创国产化战略的深入推进&#xff0c;以及万物互联时代的加速到来&#xff0c;信息技术产业正迎来前所未有的发展机遇。在这一背景下&#xff0c;成都知了汇智科技有限公司作为产教融合领域的先行者&#xff0c;积极响应国家号召&#xff0c;通过举办鸿蒙系列讲座进校园活…

Java方法(下)

1.1 方法的可变参数&#xff08;一般重要&#xff09; 规则要求 【修饰符】 class 类名{【①修饰符】 ②返回值类型 ③方法名(④数据类型... 参数名){⑤方法体语句;}【①修饰符】 ②返回值类型 ③方法名(④数据类型 参数名1, 数据类型 参数名2, 数据类型... 参数名3){⑤方法…

TongRds docker 镜像做成与迁移(by liuhui)

TongRds docker 镜像做成与迁移 一&#xff0c;使用 docker commit 命令制作 TongRds docker 镜 像 1.1 拉取基础镜像 centos 并运行该镜像 拉取镜像&#xff1a;docker pull ubuntu 镜像列表&#xff1a;docker images 运行镜像&#xff1a;docker run -itd --name myubuntu…

K8S面试题学习

参考K8S面试题&#xff08;史上最全 持续更新&#xff09;_kubernetes常见面试题-CSDN博客做的个人总结&#xff0c;规划是每天看10题&#xff0c;thx&#xff01; 1.K8S是什么&#xff1f; 容器编排工具&#xff0c;主要用来管理容器化的一个应用&#xff0c;可以管理容器全…

PyTorch Scheduler动态调整学习率

文章目录 PyTorch动态调整学习率1.使用官方scheduler2.自定义scheduler参考 PyTorch动态调整学习率 深度学习中长久以来一直存在一个令人困扰的问题&#xff0c;那就是如何选择适当的学习率。如果学习速率设置得过小&#xff0c;会导致模型收敛速度缓慢&#xff0c;训练时间延…

在k8s集群中部署EdgeMesh

1. 前置准备 1.1 移除k8s master节点污点 如果k8s master节点上没有部署需要被代理的应用&#xff0c;也可以不执行此步骤&#xff1a; kubectl taint nodes --all node-role.kubernetes.io/master- 1.2 给 Kubernetes API 服务添加过滤标签 正常情况下你不会希望 EdgeMes…

C#生成一个绿色文件

生成一个绿色文件免去了安装的繁琐过程&#xff0c;直接运行&#xff0c;非常方便。 新建一个类库项目 在类库Class1中实现简单的Sum方法。 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespac…

【Android】Activity task和Instrumentation杂谈

文章目录 activity taskInstrumentation机制参考 Android不仅可以装载众多的系统组件&#xff0c;还可以将它们跨进程组成ActivityTask&#xff0c;这个特性使得每个应用都不是孤立的。 activity task 从数据结构角度看&#xff0c;Task有先后之分&#xff0c;源码实现上采取了…

redisson -- 延迟队列RDelayedQueue

1.maven配置 <!-- 用于管理起步工程的依赖管理 --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.11</version><relativePath/> </parent…

【Linux】基础I/O>文件系统软硬链接动静态库详解

主页&#xff1a;醋溜马桶圈-CSDN博客 专栏&#xff1a;Linux_醋溜马桶圈的博客-CSDN博客 gitee&#xff1a;mnxcc (mnxcc) - Gitee.com 目录 1.C语言文件接口 1.1 hello.c写文件 1.2 hello.c读文件 1.3 输出信息到显示器 1.4 stdin & stdout & stderr 1.5 总结打…

华为OD-C卷-路口最短时间问题[200分]Java 100%

题目描述 假定街道是棋盘型的,每格距离相等,车辆通过每格街道需要时间均为 timePerRoad; 街道的街口(交叉点)有交通灯,灯的周期 T(=lights[row][col])各不相同; 车辆可直行、左转和右转,其中直行和左转需要等相应 T 时间的交通灯才可通行,右转无需等待。 现给出…

如何使用OSI七层模型的思路进行Linux网络问题排障?

在运维工作中&#xff0c;我们可能经常遇到诸如服务器无法远程连接、网站无法访问等各种网络问题。此时你是否想过&#xff0c;我们常背的OSI七层模型&#xff0c;能在处理这样的实际问题中发挥什么样的作用呢&#xff1f; 基于OSI架构的方法论&#xff0c;我们可以使用自下而…

关于系统数据缓存的思考以及设计

文章目录 引言案例A项目B项目 分析我的实现总结 引言 缓存&#xff0c;这是一个经久不衰的话题&#xff0c;它通过“空间换时间”的战术不仅能够极大提升处理查询性能还能很好的保护底层资源。最近针对系统数据缓存的优化后&#xff0c;由于这是一个通用的场景并且有了一点心得…

再拓信创版图-Smartbi 与东方国信数据库完成兼容适配认证

近日&#xff0c;思迈特商业智能与数据分析软件 [简称&#xff1a;Smartbi Insight] V11与北京东方国信科技股份有限公司 &#xff08;以下简称东方国信&#xff09;CirroData-OLAP分布式数据库V2.14.1完成兼容性测试。经双方严格测试&#xff0c;两款产品能够达到通用兼容性要…

计算机网络(王道考研)笔记个人整理——第二章

第二章 物理层主要任务&#xff1a;确定与传输媒体有关的一些特性 机械特性&#xff1a;物理连接的特性 规定物理连接时所采用的规格、接口形状、引线数目、引脚数量和排列情况 电气特性 规定传输二进制位时&#xff0c;线路上信号的电压范围、阻抗匹配、传输速率和距离限制等…

VectorMap论文阅读

1. 摘要 自动驾驶系统需要对周围环境具有很好的理解&#xff0c;包括动态物体和静态高精度语义地图。现有方法通过离线手动标注来解决语义构图问题&#xff0c;这些方法存在严重的可扩展性问题。最近的基于学习的方法产生稠密的分割预测结果&#xff0c;这些预测不包含单个地图…

Oracle——领先的企业级数据库解决方案

一、WHAT IS ORACLWE&#xff1a; ORACLE 数据库系统是美国 ORACLE 公司&#xff08;甲骨文&#xff09;提供的以分布式数据库为核心的一组软件产品&#xff0c;是目前最流行的客户/服务器(CLIENT/SERVER)或B/S 体系结构的数据库之一&#xff0c;ORACLE 通常应用于大型系统的数…