c++应用网络编程之一基本介绍
一、网络编程介绍
c++编程的应用场景在前面分析过,一个重要的方向就是网络编程。一般来说,开发者说的服务端编程在c++方向上简单的可以认为是网络编程。首先需要说明的,本系列不对网络编程的相关基础知识展开详细的说明,因为这种知识在书本上太多了。网络上各种资料更是满开飞,没有必要拷贝来拷贝去的。特别是一些协议等的解析说明,如果不遇到特定的问题不会深入分析说明。
那么最应该明白的网络编程是什么?那么就得明白网络是如何而来。网络,从名字上很好理解,一张把“经络”连接起来的大网。不过这个经络不是人体中的“经络”而是一个个节点,这个节点可以是虚拟的,也可以是物理的,也可以是混合的。它可以是一台电脑,一个手机,一个终端,也可以是一个局域网、城域网等等。
计算机的网络技术在计算机技术中算是比较早期的一种技术了,在60年代的中期就已经开始在实际应用了。但真正的普及是美国的国防用网络。早期学习电脑的或者看过早期电影的,都听说过某某黑客特别厉害,进入了五角大楼的网络,盗取了不少军事资料。可以这样讲,计算机的网络技术也是从美国开始兴起的,然后在全世界开始普及。这也解释了为什么现在最牛的互联网公司基本都在美国的一个重要原因。比如耳熟能详的谷歌、微软、脸书以及推特等等。
随着PC的出现和发展,局域网(LAN)出现。美国Xerox公司首先推出了Ethernet网,慢慢其成为了一种标准,大家都称现在的局域网络为以太网。有了局域就会有广域网WAN。不过需要说明的是,所谓局域与广域是一个相对概念,请大家一定要根据实际场景来确定。
网络技术其实就是处理PC间连接通信的技术。从物理上讲,如何识别网络中的PC,如何与其它PC交换数据等等。首先需要用物理导线将各个PC连接起来,一开始是电缆,后来光缆,再后来又有无线技术。然后还要有路由器和交换机把数据将有的传送到指定的PC。而为了实现上述的功能,就需要一系列的通信标准和通信协议。这就引出了网络协议的五层模型(七层就是个学术的东西,没啥实际应用的意义)。而这个模型中,则包含是最常见的网络编程中的TCP/IP、UDP、HTTP等最常见的网络编程技术。或者说的不准确一些,对大多数的网络编程人员来说,就是TCP/IP和UDP编程。在移动互联网中,HTTP则更为普及的被使用。至于其它的技术,基本都是相当专业的人员或者特定领域的开发者才会使用。
二、基本知识
这里不谈较老的技术和很新的技术,比如QUIC和HTTP3等。在网络编程中,可以分成两大类应用,即B/S开发和C/S开发(P2P以后专门讲),这里只谈C/S开发。即本系列主要针对C/S开发中的TCP/IP编程以及UDP的编程。只要掌握了它们的编程,其它的编程基本都差不多。在TCP/IP和UDP编程中,需要掌握一些基本的知识:
1、服务器
这个概念是一个非常容易混淆的概念,一定要区别在不同的语境和环境下的定义。在网络编程的语境下,一般是指承载网络服务软件的服务器电脑(硬件)。它可以分成网络内部自用,比如路由器、交换机等也可以只提供某种网络服务的电脑如打印服务器、邮箱服务器等。
2、服务端
服务端或服务端软件,也可以叫网络服务,在特定到C/S编程中,就是指提供连接服务的程序。一般来说,服务端是被接收连接的。
3、客户端
客户端在C/S编程中指发起连接的一端。
4、协议栈
协议栈(Protocol stack),又称协议堆叠,是计算机网络协议套件的一个具体的软件实现。
5、伯克利套接字
伯克利套接字(Berkeley sockets),也称为BSD Socket。其是一种使用C语言实现的网络编程抽象接口。现在几乎成为了互联网通信的标准接口。
6、五元组和三元组:
五元组包括:源IP地址,源端口,目的IP地址,目的端口和传输层协议。这等同于现实世界中的人和人之间的通信地址。
7、协议族
socket函数中的第一个参数中意义,也叫协议域。通常有AF_INET、AF_INET6、AF_LOCAL(或称AF_UNIX,Unix域socket)、AF_ROUTE等。协议族确定socket的地址类型,即双方必须使用相同的通信类型才可以进行以通信。如常见的AF_INET需要用32位(类似192.168.0.1)ipv4地址与16位端口号(最大65535)的组合、AF_UNIX需要用一个绝对路径名作为地址。
当然,还有很多的基础性的知识和名词术语。网络技术是一个发展了很多年的技术,它既成熟又年轻。举一个简单的例子,当有一个人说他是搞服务端编程的,如何确定他的技术栈?其实这个定义非常难确定,网上一些大牛的说明其实也不能够完全覆盖相关的内容,即他们的定义也是不严谨的。但仅从经验和学识来推断,特定到C/c++中,它一般是指TCP/IP编程的相关技术栈(当然,它也不严谨)。
再举一个实际的例子,大家去品一下上面这段话,至于能理解多少看自身了。在某电力部门,要求把服务端程序部署在终端上,把客户端程序部署在服务器上。客户端要24*7运行,服务端可以允许断线。
注意:再次说明,本系列不是对网络编程技术基础知识的详细分析说明,是对c++在网络编程上的应用分析说明,所以只对相关的一些知识点进行指出和简要的说明。更多的相关知识,请自行查阅下面提供的书籍和资料!
三、简单示例
虽然网络编程的例子多之又多,但这里还是要给一个简单的例子:
服务端:
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>int main() {int server_fd, new_socket;struct sockaddr_in address;int opt = 1;int addrlen = sizeof(address);char buffer[1024] = {0};const char* msg = "hello moto!";//创建socketif ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("socket failed");exit(EXIT_FAILURE);}//设置选项if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {perror("setsockopt");exit(EXIT_FAILURE);}//地址设置address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons( 8888 );//绑定端口if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0) {perror("bind err");exit(EXIT_FAILURE);}//监听if (listen(server_fd, 5) < 0) {perror("listen");exit(EXIT_FAILURE);}//接受连接if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0) {perror("accept err!");exit(EXIT_FAILURE);}send(new_socket , msg , strlen(msg) , 0 );printf("send msg ...\n");memset(buffer, '\0' , 1024);int ret = recv( new_socket , buffer, 1024,0);printf("%s\n",buffer );return 0;
}
客户端:
#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>int main() {int sock = 0, ret;struct sockaddr_in serv_addr;const char* msg = "hello !";char buffer[1024] = {0};//创建socketif ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {printf("\n Socket error \n");return -1;}serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(8888);//转换地址if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0) {printf("\n Invalid address \n");return -1;}//连接serverif (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {printf("\n Connection err \n");return -1;}send(sock , msg , strlen(msg) , 0 );printf("send msg !\n");ret = recv( sock , buffer, 1024,0);printf("%s\n",buffer );return 0;
}
写这种测试的小例程有一个需要注意的地方,客户端发送完成后,不要立即退出,否则可能服务端收不到相关的消息。
四、推荐的资料和书籍
一如在VC编程上侯捷教师是一个令开发者仰望的山峰,在网络编程也有很多更高的高峰。比如常见的推荐的《TCP/IP详解》三卷和《Unix网络编程》两卷的作者W. Richard Stevens(当然他写的APUE也相当的出名)。不过这些书的缺点也有,就是太老了。导致一些技术已经落后而一些新技术没有体现出来。其它国外的还有不少就不一一列举。国内也有几个比较有名气的网络开发者,限定到本文这个场景非常推荐MUDUO库的作者陈硕。当然就像江湖中一样,肯定还有很多高手隐身不出。
学习网络编程的书籍非常多,比如CSDN的孟岩大佬的“四书五经”之说就是为多数大牛推荐的。这里简单罗列一下:
1、TCP/IP详解(三卷)(TCP/IP Illustrated)
2、Unix网络编程(两卷)(UNIX Network Programming)
3、TCP/IP高级编程(Effective TCP/IP Programming)
4、C++网络编程(两卷)(C++ Network Programming)
虽然这些书籍非常不错,但对于初学者未必就合适,也推荐一些比较容易借鉴学习的书籍:
1、《Linux多线程服务端编程》 陈硕
2、《Linux高性能服务端编程》 游双
3、《Windows网络与通信程序设计》 王艳平
并不是说其它的书籍不值得推荐,是觉得这几本书更容易被学习和接受。至于网络上的资料就更多了,如陈硕、原网易的云风等人的BLOG都非常值得一看。个人的建议是,要根据自己的实际情况来决定学习成长的路线,不要人云亦云。大牛们给的建议可能对大多数人都是非常好的,但具体到某些个体,可能会有所不妥。大家要知道如何不断的根据大牛们的建议因地制宜的学习。
另外在网上还存在着大量的网络框架如C++网络编程中的ACE,还有libevent,libuv,libev,libeio,libhv,asio,poco等等。毕竟网络应用是一个非常高频的应用,也是很多开发者想登顶的希望。
其实还有很多应用程序中也有非常好的例子,比如REDIS,有时间推荐看看内部如何跨平台实现了网络服务端的编程。
五、总结
网络编程是一个复杂的应用,一般来说,很难在一两年内达到熟练掌握的程度,更不要谈精通了。通常,把基础的网络知识学习完成,头脑中有一个相对完整的网络编程概念,然后在实际应用中不断的加以印证,才能更快更好的掌握网络编程。
网络编程其实是一个简单应用易,复杂应用极难的技术。它不仅是涉及到网络相关的技术,还包括内存管理、多线(进)程以及异步编程等很多技术,甚至是否需要跨平台跨系统等。对大多数开发者言,网络编程的应用一般都是比较简单的应用,并发通常也就是十个量级左右,而且经常类似于交互式通信那种情况。对多线程和异步的要求不高甚至没有,对内存管理和效率的要求也不严格。
但当真正到了C10K以上的编程时,复杂程度立刻便上来,导致很多开发者没有一个过渡便直面这些复杂的应用。也就是说,在网络编程大多数的编程场景是要么简单,要么复杂,中等的开发场景非常少。而且从设计上考虑,一旦到了中等的场景,优秀的架构师通常会考虑扩展的情况下设计成更为复杂的框架结构。
复杂的网络编程,导致很多的框架的出现,而这些框架的出现更是切断了大多数开发者对背后复杂结构的理解,导致一个从初级网络编程到高级网络编程的连续而完整的流程,即要么只会简单的编程,要么只会在框架下完成各种场景的应用。
更何况,网络编程的实际要求仍然在不断的增长,这也是前面分析DPDK和XDP等的一些重要原因。换句话说,网络编程的技术仍然在不断的进步。所以,不断的学习才能保证在网络编程的方向上有更大的发展。
相关文章:
c++应用网络编程之一基本介绍
一、网络编程介绍 c编程的应用场景在前面分析过,一个重要的方向就是网络编程。一般来说,开发者说的服务端编程在c方向上简单的可以认为是网络编程。首先需要说明的,本系列不对网络编程的相关基础知识展开详细的说明,因为这种知识…...

Web后端开发概述环境搭建项目创建servlet生命周期
Web开发概述 web开发指的就是网页向后再让发送请求,与后端程序进行交互 web后端(javaEE)程序需要运行在服务器中 这样前端才可以对其进行进行访问 什么是服务器? 解释1: 服务器就是一款软件,可以向其发送请求,服务器会做出一个响应.可以在服务器中部署文件,让…...
Java 位运算详解
位运算是一种直接在二进制位上进行操作的方式。位运算符包括按位与 (&)、按位或 (|)、按位异或 (^)、按位非 (~)、左移 (<<)、右移 (>>) 和无符号右移 (>>>)。这些操作符用于操作整型数据类型,如 int 和 long。 一、按位与 (&) 按位…...

智能体实战:开发一个集成国内AI平台的GPTs,自媒体高效智能助手
文章目录 一,什么是GPTs二,开发GPTs1,目标2,开发2.1 打开 GPTS:https://chat.openai.com/gpts2.2 点击 Create 创建一个自己的智能体 2.3 配置GPTs2.4 配置外挂工具2.4.1 配置Authentication-授权2.4.1.1 生成语聚AI的…...

完美世界|单机版合集(共22个版本)
前言 我是研究单机的老罗,今天给大家带来的是完美世界的单机版合集,一共22个版本。本人亲自测试了一个版本,运行视频如下: 完美世界|单机版合集 先看所有的版本的文件,文件比较大,准备好空间,差…...
Jenkins的一些记录
设置环境变量 在 Jenkins 流水线中,取决于使用的是声明式还是脚本式流水线,设置环境变量的方法不同。 声明式流水线支持 environment 指令,而脚本式流水线的使用者必须使用 withEnv 步骤。 pipeline {agent anyenvironment { CC clang}stag…...
讲讲js中的prototype和__proto__
在Javascript中,prototype和__proto__是两个重要的概念,在对象的原型链中扮演重要的角色。 prototype prototype是js函数的内置属性,每个函数都有一个prototype属性,它是一个指针,指向一个对象(原型对象&a…...

JavaScript的学习之DOM的查询(一)
一、获得元素 通过document对象调用: getElementById():通过id属性获取一个元素节点对象getElementsByTagName():通过标签名获取一组元素节点对象getElementsByName():通过name属性来获取一组元素节点对象 核心学习代码 <scrip…...

充电宝哪个品牌比较好一点?多维度实测西圣、绿联、倍思充电宝!
在这个快节奏的时代,智能手机已成为我们日常生活不可或缺的一部分,而充电宝作为其能量补给站,重要性不言而喻。面对市场上琳琅满目的充电宝品牌与型号,如何挑选一款既实用又高效的充电伴侣,成为了许多消费者的难题。今…...
ubuntu安装QT
以QT5.15.14为例 下载地址:Index of /archive/qt 安装步骤: 解压qt-everywhere-src-5.15.14运行: cd qt-everywhere-src-5.15.14 mkdir build cd build ../configure -prefix /opt/qt5.15.14 -opensource -confirm-license make -j16 sudo…...

DataGrip 2024 po for Mac 数据库管理工具解
Mac分享吧 文章目录 效果一、下载软件二、开始安装1、双击运行软件(适合自己的M芯片版或Intel芯片版),将其从左侧拖入右侧文件夹中,等待安装完毕2、应用程序显示软件图标,表示安装成功3、打开访达,点击【文…...
《C++ Primer》导学系列:第 13 章 - 拷贝控制
13.1 拷贝、赋值与析构函数 拷贝控制是C++中类设计的重要组成部分,用于管理对象的复制、赋值和销毁过程。理解并正确实现拷贝控制函数(拷贝构造函数、拷贝赋值运算符和析构函数)对于编写健壮和高效的C++程序至关重要。 13.1.1 拷贝构造函数 拷贝构造函数用于创建对象的副…...
c++ 图论2 深度优先算法和广度优先算法
修改一下深度优先算法和广度优先算法,标出每一个节点相对于遍历起始位置的层级,遍历起始起点为第一层,和第一层相连的节点为第二层,以此类推 定义一个新的结构 struct NodeWithLevel {TreeNode* node;int level;NodeWithLevel(T…...

【Qt】初识QtQt Creator
一.简述Qt 1.什么是Qt Qt 是⼀个 跨平台的 C 图形⽤⼾界⾯应⽤程序框架 。它为应⽤程序开发者提供了建⽴艺术级图形界⾯所需的所有功能。它是完全⾯向对象的,很容易扩展。Qt 为开发者提供了⼀种基于组件的开发模式,开发者可以通过简单的拖拽和组合来实现…...

Android 11.0 修改系统显示大小导航栏消失
Android 11.0 修改系统显示大小导航栏消失 1.显示大小设置为大时,导航栏图标不显示。 设置为大,较大,最大时,导航栏图标不显示。 2.开始怀疑是导航栏被隐藏了,各种折腾无效。 3.发现: frameworks/base/pa…...

RocketMQ源码学习笔记:Producer启动流程
这是本人学习的总结,主要学习资料如下 马士兵教育rocketMq官方文档 目录 1、Overview1.1、创建MQClientInstance1.1.1、检查1.1.1、MQClientInstance的ID 1.2、MQClientInstance.start() 1、Overview 这是发送信息的代码样例, DefaultMQProducer produ…...
Node.js 和浏览器环境中都使用 WebSocket
使用WebSocket为什么不适配双端 浏览器环境本身就支持 WebSocket,直接使用 JavaScript 内置的 WebSocket 对象来建立连接。 Node中本身并没有内置 WebSocket 协议的支持,所以需要使用第三方库 ws来实现 WebSocket 功能。 一. 使用跨平台 WebSocket 库 …...

css美化滚动条样式
效果展示 实现 滚动条宽,高度 /* 整体滚动条 */ ::-webkit-scrollbar {width: 10px; }/* 滚动条轨道 */ ::-webkit-scrollbar-track {background-color: #ffffff;border-radius: 6px; }/* 滚动条滑块 */ ::-webkit-scrollbar-thumb {background-color: #888;borde…...
由浅入深,走进深度学习(补充篇:转置卷积和FCN)
本期内容是针对神经网络层结构的一个补充,主要内容是:转置卷积和全连接卷积网络 相关内容: 由浅入深,走进深度学习(2)_卷积层-CSDN博客 由浅入深,走进深度学习(补充篇:…...

Linux基础篇——目录结构
基本介绍 Linux的文件系统是采用级层式的树状目录结构,在此结构中的最上层是根目录"/",然后在根目录下再创建其他的目录 在Linux中,有一句经典的话:在Linux世界里,一切皆文件 Linux中根目录下的目录 具体的…...

springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...

Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...