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(字段名称 字段数据类型…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...

JDK 17 序列化是怎么回事
如何序列化?其实很简单,就是根据每个类型,用工厂类调用。逐个完成。 没什么漂亮的代码,只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...
RLHF vs RLVR:对齐学习中的两种强化方式详解
在语言模型对齐(alignment)中,强化学习(RL)是一种重要的策略。而其中两种典型形式——RLHF(Reinforcement Learning with Human Feedback) 与 RLVR(Reinforcement Learning with Ver…...

无头浏览器技术:Python爬虫如何精准模拟搜索点击
1. 无头浏览器技术概述 1.1 什么是无头浏览器? 无头浏览器是一种没有图形用户界面(GUI)的浏览器,它通过程序控制浏览器内核(如Chromium、Firefox)执行页面加载、JavaScript渲染、表单提交等操作。由于不渲…...

Unity VR/MR开发-开发环境准备
视频讲解链接: 【XR马斯维】UnityVR/MR开发环境准备【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...
全面解析网络端口:概念、分类与安全应用
在计算机网络的世界里,数据的传输与交互如同一场繁忙的物流运输,而网络端口就是其中不可或缺的 “货运码头”。无论是日常浏览网页、收发邮件,还是运行各类网络服务,都离不开网络端口的参与。本文将深入介绍网络端口的相关知识&am…...