c++网络编程
网络编程模型
c/s 模型:客户端服务器模型b/s 模型:浏览器服务器模型
1.tcp网络流程

服务器流程:
1.创建套接字2.完善服务器网络信息结构体3.绑定服务器网络信息结构体4.让服务器处于监听状态5.accept阻塞等待客户端连接信号6.收发数据7.关闭套接字
客户端流程:
1.创建套接字2.连接connect3.收发数据4.关闭套接字
2.函数
2.1socket
#include <sys/types.h>
#include <sys/socket.h>int socket(int domain, int type, int protocol);
功能:创建套接字参数:domain:通信域Name Purpose Man pageAF_UNIX,AF_LOCAL Local communication(本地通信) unix(7)AF_INET IPv4 Internet protocols ip(7)AF_INET6 IPv6 Internet protocols ipv6(7)AF_PACKET 原始套接字 packet(7)type:套接字的类型SOCK_STREAM TCPSOCK_DGRAM UDP使用SOCK_RAW 原始套接字使用protocol:附加文件,没有写0返回值:成功:创建的新套接字(文件描述符)失败:-1 重置错误码
2.2bind
#include <sys/types.h>
#include <sys/socket.h>int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
功能:绑定套接字和网络信息结构体参数:sockfd:socket函数产生的套接字文件描述符(socket函数返回值)addr:避免冲突警告
2.3listen
#include <sys/types.h>
#include <sys/socket.h>int listen(int sockfd, int backlog);产生半连接队列功能:将套接字设置成被动监听状态,只有这个状态的套接字才能等待客户端连接参数:sockfd:socket函数返回值backlog:半连接队列的长度,一般传 5 10 都行 不是0就行返回值:成功:0失败:-1 重置错误码
accept
#include <sys/types.h>
#include <sys/socket.h>int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);产生全连接队列,返回值创 建的文件描述符
功能:提取半连接队列中的第一个客户端连接,成功,放到函数产生的全连接队列中,专门 用于和当前客户端通信,返回的套接字和原套接字类型相同参数:sockfd:listen后的sockfdaddr:客户端的网络信息结构体首地址,不关心写NULLaddrlen:客户端addr长度,不关心写NULL返回值:成功:创建的新的文件描述符 专门用于和当前客户端通信失败:-1 重置错误码
connect
#include <sys/types.h>
#include <sys/socket.h>int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);功能:与服务器建立连接 参数:sockfd:accept函数返回值addr:服务器的网络信息结构体addrlen:addr的长度返回值:成功:0失败:-1 重置错误码
服务器代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <string.h>
#include <arpa/inet.h>
#define ERRLOG(msg) do{\printf("%s %s %d\n", __FILE__, __func__, __LINE__);\perror(msg);\exit(-1);\}while(0)int main(int argc, char const *argv[])
{//1.创建套接字int sockfd=0;//需要接函数返回值,后面函数会用if(-1==(sockfd=socket(AF_INET,SOCK_STREAM,0))){ERRLOG("socket error");}//2.服务器网络信息结构体填充//struct sockaddr addr;struct sockaddr_in ad;memset(&ad, 0, sizeof(ad));ad.sin_family=AF_INET;ad.sin_port=htons(7788);//自己随意指定,不冲突就行,冲突就换ad.sin_addr.s_addr=inet_addr("192.168.250.100");//3.绑定套接字和服务器网络信息结构体if(-1==bind(sockfd,(struct sockaddr*)&ad,sizeof(ad))){ERRLOG("bind error");}//4.让套接字处于被动监听状态if(-1==listen(sockfd,5)){ERRLOG("listen error");}//5.阻塞等待客户端连接printf("正在等待客户端发来信息\n");int newfd=0;if((newfd=accept(sockfd,NULL,NULL))==-1){ERRLOG("accept error");}printf("客户端连接成功\n");//6.收发数据char buff[128]={0};int lnum=0;char opr=0;int rnum=0;int result=0;read(newfd,buff,128);printf("客户端发来数据:%s\n",buff);sscanf(buff,"%d%c%d",&lnum,&opr,&rnum);switch(opr){case '+':result=lnum+rnum;break;case '-':result=lnum-rnum;break;case '*':result=lnum*rnum;break;case '/':result=(float)lnum/(float)rnum;break;}memset(buff,0,128);sprintf(buff,"result=%d",result);write(newfd,buff,128);//7.关闭套接字close(sockfd);close(newfd);return 0;
}
客户端代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <string.h>
#include <arpa/inet.h>#define ERRLOG(msg) do{\printf("%s %s %d\n", __FILE__, __func__, __LINE__);\perror(msg);\exit(-1);\}while(0)int main(int argc, char const *argv[])
{//创建套接字int sockfd=0;if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){ERRLOG("socket error");}//填充服务器结构体struct sockaddr_in addr;memset(&addr, 0, sizeof(addr));addr.sin_family=AF_INET;addr.sin_port=htons(6666);addr.sin_addr.s_addr=inet_addr("192.168.2.84");//连接服务器if(connect(sockfd,(struct sockaddr *)&addr,sizeof(addr))==-1){ERRLOG("connect error");}//收发数据char buff[128]={0};//写入的数据从终端获取fgets(buff,128,stdin);buff[strlen(buff)-1]='\0';write(sockfd,buff,128);memset(buff,0,128);read(sockfd,buff,128);printf("服务器发来的信息是:%s\n",buff);//7.关闭套接字close(sockfd);return 0;
}
send
#include <sys/types.h>
#include <sys/socket.h>ssize_t send(int sockfd, const void *buf, size_t len, int flags);ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);功能:发送数据参数:sockfd:accept函数返回值buf:要发送的数据的缓冲区首地址len:要发送数据的长度flags:发送的标志位,0用法和write就一样了,MSG_DONTWAIT 表示非阻塞返回值:成功:实际发送的字节数失败:-1 重置错误码注意:如果对方关闭了套接字或者断开连接第一次send没有反应,第二次send会产生SIGPIPE信号下面三种用法是等价的:write(sockfd, buf, 128);send(sockfd, buf, 128, 0);sendto(sockfd, buf, 128, 0, NULL, NULL);
recv
#include <sys/types.h>
#include <sys/socket.h>ssize_t recv(int sockfd, void *buf, size_t len, int flags);ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);功能:接收数据 参数:sockfd:accept函数返回值buf:要接收的数据的缓冲区首地址len:要接收数据的长度flags:发送的标志位,flags:接收的标志位,0用法和read就一样了, MSG_DONTWAIT 表示非阻塞返回值:成功:实际接收的字节数失败:-1 重置错误码注意: 如果对方关闭了套接字或者断开连接 recv 会返回0下面三种用法是等价的:read(sockfd, buf, 128);recv(sockfd, buf, 128, 0);recvfrom(sockfd, buf, 128, 0, NULL, NULL);
粘包问题产生原因
tcp在传输的时候不是一调用send就直接将数据发送给客户端的,而是将数据放到发送缓冲区里
tcp底层的nagle算法,会将一定短时间内发送的数据包组装成一个整体,发送给对方
而接受方无法区分消息的边界和类型,就可能会导致有冲突的情况发生
也就是说,当文件只剩最后一部分的时候,很有可能将最后的结束字符和文件最后一部分作为一个整体发送给接收方,也有可能将三个128和最后的30+12一起发给接收方,但不管是哪种方式,接收方写入的时候是以128为单位接受的,所以接收方缓冲区里是无法单独比较over的,所以会产生粘包问题。
解决方法:
1.既然是一定短时间内的数据成为一个整体,那么最后发送的over就不和前面一块发送了,在over之前加一个延时函数,让他单独发送
但是不常用,因为服务器里禁止使用sleep
2.发送定长的数据包,
解决方法一代码
相关文章:
c++网络编程
网络编程模型 c/s 模型:客户端服务器模型b/s 模型:浏览器服务器模型1.tcp网络流程 服务器流程: 1.创建套接字2.完善服务器网络信息结构体3.绑定服务器网络信息结构体4.让服务器处于监听状态5.accept阻塞等待客户端连接信号6.收发数据7.关闭套…...
【沁恒蓝牙mesh】数据收发接口与应用层模型传递
本文主要描述了沁恒蓝牙mesh SDK的蓝牙数据收发接口,以及应用层的回调函数解析以及模型传递 这里写目录标题 1. 数据收发接口1.1【发送数据】1.2 【数据接收】 2. 应用层模型分析 1. 数据收发接口 1.1【发送数据】 /*(1)接口1 */ /*接口一&…...
Java类关系之代理(代理模式)
在Java中,如果一个类需要使用另一个类的方法,我们可以使用继承的方式实现,那么问题来了,如果这个类恰恰在逻辑关系上不能使用继承怎么办呢?比如说,飞机和控制台这两个类,控制台的方法有上下左右…...
java: 无法访问redis.clients.jedis.JedisPoolConfig
问题描述: 在编译java springboot程序的时候报错 java: 无法访问redis.clients.jedis.JedisPoolConfig 找不到redis.clients.jedis.JedisPoolConfig的类文件 问题分析 该问题是由于找不到JedisPoolConfig包导致的,很可能是没有添加相关的依赖 问题解决 在pom文件中添加依赖项…...
基于java中学教务管理系统设计与实现
摘要 随着现代技术的不断发展,计算机已经深度的应用到了当下的各个行业之中,教育行业也不例外。计算机对教育行业中的教务管理等内容的帮助,使得教职工从传统的手工办公像计算机辅助阶段迈进,并且实现了非常好的发展。现在的学校在…...
vscode设置java -Xmx最大堆内存
如果在vscode中直接运行java程序,想要改下每次运行的最大堆内存,按照如下修改 一、vscode安装java插件 当然前提是vscode在应用管理中已经安装了java语言的插件,Debugger for Java,如下图所示 二、CommandShiftP打开配置搜索框 三、搜索…...
组件开发系列--Apache Commons Chain
一、前言 Commons-chain是apache commons中的一个子项目,主要被使用在"责任链"的场景中,struts中action的调用过程,就是使用了"chain"框架做支撑.如果你的项目中,也有基于此种场景的需求,可以考虑使用它. 在责任链模式里,很多对象由每一个对象对…...
60 # http 的基本概念
什么是 HTTP? 通常的网络是在 TCP/IP 协议族的基础上来运作的,HTTP 是一个子集。http 基于 tcp 的协议,在 tcp 的基础上增加了一些规范,就是 header,学习 http 就是学习每个 header 它有什么作用。 TCP/IP 协议族 协…...
云计算迎来中场战役,MaaS或将成为弯道超车“新赛点”
科技云报道原创。 没有人能预见未来,但我们可以因循常识,去捕捉技术创新演进的节奏韵脚。 2023年最火的风口莫过于大模型。 2022年底,由美国初创企业OpenAI开发的聊天应用ChatGPT引爆市场,生成式AI成为科技市场热点,…...
最新基于Citespace、vosviewer、R语言的文献计量学可视化分析技术及全流程文献可视化SCI论文高效写作方法
文献计量学是指用数学和统计学的方法,定量地分析一切知识载体的交叉科学。它是集数学、统计学、文献学为一体,注重量化的综合性知识体系。特别是,信息可视化技术手段和方法的运用,可直观的展示主题的研究发展历程、研究现状、研究…...
Hive调优集锦(2)
3.8 Join 优化 Join优化整体原则: 1、优先过滤后再进行 join 操作,最大限度的减少参与 join 的数据量 2、小表 join 大表,最好启动 mapjoin,hive 自动启用 mapjoin, 小表不能超过25M,可以更改 3、Join on的条件相同的…...
一文谈谈Git
"And if forever lasts till now Alright" 为什么要有git? 想象一下,现如今你的老师同时叫你和张三,各自写一份下半年的学习计划交给他。 可是你的老师是一个极其"较真"的人,发现你俩写的学习计划太"水&…...
嵌入式数据库之SQLite
1.SQLite简介 轻量化,易用的嵌入式数据库,用于设备端的数据管理,可以理解成单点的数据库。传统服务器型数据 库用于管理多端设备,更加复杂。 SQLite是一个无服务器的数据库,是自包含的。这也称为嵌入式数据库&#x…...
idea下tomcat运行乱码问题解决方法
idea虚拟机选项添加-Dfile.encodingUTF-8...
人工智能TensorFlow MNIST手写数字识别——实战篇
上期文章TensorFlow手写数字-训练篇,我们训练了我们的神经网络,本期使用上次训练的模型,来识别手写数字(本期构建TensorFlow神经网络代码为上期文章分享代码) http://scs.ryerson.ca/~aharley/vis/conv/ 0、插入第三方库 from PIL import Image# 处理图片 import tensorf…...
Vue 本地应用-计数器
逻辑是在点击按钮的时候执行,那么要为按钮绑定点击事件,整体语法如下: <!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>首页</title><link href"" type"text/c…...
深入了解HTTP代理在网络爬虫与SEO实践中的角色
随着互联网的不断发展,搜索引擎优化(SEO)成为各大企业和网站重要的推广手段。然而,传统的SEO方法已经难以应对日益复杂和智能化的搜索引擎算法。在这样的背景下,HTTP代理爬虫作为一种重要的工具,正在逐渐被…...
使用docker搭建nacos
使用docker搭建nacos docker搭建最新版nacosMySQL下简历nacos配置数据表拉取镜像创建挂载目录启动容器访问nacos docker搭建nacos 2.0版本 docker搭建最新版nacos 最近想在自己服务器上搭建一个nacos服务,以前一直在本地的windows上使用,而且使用着naco…...
flask中的常用装饰器
flask中的常用装饰器 Flask 框架中提供了一些内置的装饰器,这些装饰器可以帮助我们更方便地开发 Web 应用。以下是一些常用的 Flask 装饰器: app.route():这可能是 Flask 中最常用的装饰器。它用于将 URL 路由绑定到一个 Python 函数&#x…...
SQL基础语法 | 增删改查、分组、排序、limit
Shell命令框和Navicat联合使用 一、数据库层面 创建数据库 postgres# CREATE DATABASE runoobdb;查看数据库 postgres# \l选择数据库 postgres# \c runoobdb删除数据库 postgres# DROP DATABASE runoobdb;二、表格层面 创建表格 CREATE TABLE table_name(字段名称 字段数据类型…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...
ubuntu22.04 安装docker 和docker-compose
首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...
uni-app学习笔记三十五--扩展组件的安装和使用
由于内置组件不能满足日常开发需要,uniapp官方也提供了众多的扩展组件供我们使用。由于不是内置组件,需要安装才能使用。 一、安装扩展插件 安装方法: 1.访问uniapp官方文档组件部分:组件使用的入门教程 | uni-app官网 点击左侧…...
用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章
用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章 摘要: 操作系统内核的安全性、稳定性至关重要。传统 Linux 内核模块开发长期依赖于 C 语言,受限于 C 语言本身的内存安全和并发安全问题,开发复杂模块极易引入难以…...
【Ftrace 专栏】Ftrace 参考博文
ftrace、perf、bcc、bpftrace、ply、simple_perf的使用Ftrace 基本用法Linux 利用 ftrace 分析内核调用如何利用ftrace精确跟踪特定进程调度信息使用 ftrace 进行追踪延迟Linux-培训笔记-ftracehttps://www.kernel.org/doc/html/v4.18/trace/events.htmlhttps://blog.csdn.net/…...
表单设计器拖拽对象时添加属性
背景:因为项目需要。自写设计器。遇到的坑在此记录 使用的拖拽组件时vuedraggable。下面放上局部示例截图。 坑1。draggable标签在拖拽时可以获取到被拖拽的对象属性定义 要使用 :clone, 而不是clone。我想应该是因为draggable标签比较特。另外在使用**:clone时要将…...
