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

devtools/2024/12/22 9:12:11/

目录

  • 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/devtools/2067.html

相关文章

Leetcode - 周赛393

目录 一&#xff0c;3114. 替换字符可以得到的最晚时间 二&#xff0c;3115. 素数的最大距离 三&#xff0c;3116. 单面值组合的第 K 小金额 四&#xff0c; 3117. 划分数组得到最小的值之和 一&#xff0c;3114. 替换字符可以得到的最晚时间 本题是一道模拟题&#xff0c;…

阿里云服务器怎么更换暴露的IP

很多客户阿里云服务器被攻击IP暴露&#xff0c;又不想迁移数据换服务器&#xff0c;其实阿里云服务器可以更换IP&#xff0c;今天就来和大家说说流程&#xff0c;云服务器创建成功后6小时内可以免费更换公网IP地址三次&#xff0c;超过6小时候就只能通过换绑弹性公网IP的方式来…

Linux网络服务器编程:TCP与UDP详解

文章目录 一、TCP与UDP概述1.1 TCP的原理1.2 UDP的原理1.3 数据流动 二、Socket的使用2.1 TCP Socket示例2.2 UDP Socket示例 三、数据流动时序图3.1 TCP通信详解3.2 UDP通信详解 四、异常情况处理4.1 服务器ACK丢失4.2 第三次握手的ACK丢失 五、总结推荐阅读 Linux网络服务器编…

【机器学习】分类与预测算法评价的方式介绍

一、引言 1、机器学习分类与预测算法的重要性 在数据驱动的时代&#xff0c;机器学习已经成为了处理和分析大规模数据的关键工具。分类与预测作为机器学习的两大核心任务&#xff0c;广泛应用于各个领域&#xff0c;如金融、医疗、电商等。分类算法能够对数据进行有效归类&…

基于react native的android原生微信客服,微信支付以及判断是否安装微信

基于react native的android原生微信客服&#xff0c;微信支付以及判断是否安装微信 引入SDK&#xff08;Android Studio 环境下&#xff09;创建wxapi/WXPayEntryActivity.java&#xff08;用于接收微信响应返回信息&#xff09;CustomerServiceModule.javaCustomerServicePack…

工业级3D可视化工具HOOPS Visualize, 快速构建移动端和PC端工程应用程序!

HOOPS Visualize是一款强大的工业级3D渲染引擎&#xff0c;帮助您打造出众的工程应用程序。HOOPS Visualize的基石是图形内核&#xff0c;这是一种全功能的&#xff0c;以工程为重点的场景图技术&#xff0c;我们称为Core Graphics。Core Graphics集成到一个框架中&#xff0c;…

客服话术沟通技巧:客服怎么礼貌表达拒绝?

在客服工作中&#xff0c;面对消费者的不同需求和请求&#xff0c;如何礼貌而有效地表达“拒绝”是一项重要的沟通技巧。对于提升客户满意度和客服响应率极为重要。下面给大家分享一些客服话术沟通技巧。 一、客服话术沟通技巧 1.退差价&#xff08;售后不能退&#xff09;&am…

three.js捋文档的记录笔记(六):场景 几何体 材质 物体 相机 渲染器的简单理解

三维场景Scene const scene new THREE.Scene();物体形状&#xff1a;几何体 Geometry //创建一个长方体几何对象Geometry const geometry new THREE.BoxGeometry(100, 100, 100); 物体外观&#xff1a;材质Material //创建一个材质对象Material const material new THREE.M…