当前位置: 首页 > news >正文

网络的基本概念和socket编程

网络的基本概念

  • 1.协议
    • 1.1 协议的基本概念
    • 1.2 常见的协议
  • 2.分层模型
      • 2.1网络七层OSI 7层模型:物数网传会表应(口诀)
      • 2.2TCP/IP模型
      • 2.3数据通信的过程
      • 2.4网络的设计模式
      • 2.5以太网帧的格式
  • 3.SOCKET编程
    • 3.1网络字节序
    • 3.2 相关结构体和函数
    • 3.3 代码实现

1.协议

1.1 协议的基本概念

协议:双方共同指定的一组规则,在网络通信中指通信双方传递数据和通信双方传递数据和解释数据的一组规则。

1.2 常见的协议

  1. TCP/IP协议:传输控制协议/互联网协议是互联网通信的基础协议。它将数据分割成小的数据包进行传输,并通过IP地址定位目标设备。

  2. HTTP协议:超文本传输协议是用于在网络中传输超文本的应用层协议。它用于在Web浏览器和Web服务器之间传输HTML页面。

  3. FTP协议:文件传输协议是用于在网络中传输文件的协议。它允许用户在客户端和服务器之间进行文件的上传和下载。

  4. SMTP协议:简单邮件传输协议是用于在网络中传输电子邮件的协议。它定义了如何发送和接收电子邮件。

  5. DHCP协议:动态主机配置协议是用于在一个网络中自动分配IP地址的协议。它允许设备动态获取IP地址、子网掩码、网关等网络配置信息。

  6. DNS协议:域名系统是将域名解析为IP地址的协议。它通过将用户输入的域名转换为IP地址,使得计算机能够找到目标服务器。

  7. Telnet协议:用于在网络上远程登录到其他计算机进行操作和管理。

  8. SSH协议:和Telnet相似,但是提供了更加安全的远程登录方式。

  9. .SSL/TLS协议:用于在网络上进行安全的通信,提供数据加密和认证功能,常用于安全的网页浏览、电子商务等。

这些协议在网络通信、电子邮件、安全通信和文件传输等方面起到了重要的作用。

2.分层模型

2.1网络七层OSI 7层模型:物数网传会表应(口诀)

应用层:为客户提供各种应用服务,email服务,ftp服务,ssh服务。
表示层:编解码,翻译工作。
会话层:通过传输层建立数据传输的通道,建立,维护,终止会话。
传输层:传输数据,TCP,UDP协议,端对端传输。
网络层:定义了网络,两台机器之间的传输路径选择点对点传输。
数据链路层(网络接口层):数据校验,定义了网络传输的基本单位–帧。
物理层:双绞线,光纤(传输介质),将模拟信号信号转化为数字信号。

在这里插入图片描述

2.2TCP/IP模型

在这里插入图片描述

2.3数据通信的过程

在这里插入图片描述
在数据发送方是一个层层打包的过程,数据接收方是一个层层解包的过程。

2.4网络的设计模式

网络的设计模式,有B/S模式和C/S模式。

C/S模式:

客户端----服务器结构。C/S结构在技术上很成熟,它的主要特点是交互性强、具有安全的存取模式、网络通信量低、响应速度快、利于处理大量数据。因为客户端要负责绝大多数的业务逻辑和UI展示,又称为胖客户端。它充分利用两端硬件,将任务分配到Client和Server两端,降低了系统的通讯开销。C/S结构的软件需要针对不同的操作系统系统开发不同版本的软件,加之产品的更新换代十分快,已经很难适应百台电脑以上局域网用户同时使用

硬件环境要求:C/S 用户固定,一般只应用于局域网中,要求拥有相同的操作系统,如果对于不同操作系统还要相应开发不同的版本,并且对于计算机电脑配置要求也较高。

B/S模式:
浏览器----服务器结构,是目前应用系统的发展方向。BS是伴随着Internet技术的兴起,对C/S架构的改进,为了区别于传统的C/S模式,特意称为B/S模式。在这种结构下,通过W3浏览器来进入工作界面,极少部分事务逻辑在前端(Browser)实现,主要事务逻辑在服务器端(Server)实现,形成三层(3-tier)结构。这样使得客户端电脑负荷大大简化(因此被称为瘦客户端),减轻了系统维护、升级的支出成本,降低了用户的总体成本(TCO)。

硬件环境要求:要求有操作系统和浏览器就行,与操作系统平台无关(可以实现跨平台),对客户端的计算机电脑配置要求较低。

2.5以太网帧的格式

在这里插入图片描述这里的目的地址和源地址都是指MAC地址,MAC地址为6个字节,IP地址为4个字节,不同类型对应了不同的值,CRC是进行校验的。

下面我们我们来以ARP请求包,假如我们有狠多的机器,我们想给其中一个机器建立对话,我们不知道它的MAC地址只知道IP地址,那么我们如何建立会话呢?
在这里插入图片描述现在我们来看看以太网帧,以ARP为例。

这里是ARP请求包,不知道的mac地址我们填ff:ff:ff:ff:ff:ff。

在这里插入图片描述

如果这个IP地址和自己一样,给A机器发一个ARP应答包。

在这里插入图片描述

3.SOCKET编程

3.1网络字节序

socket编程之前,我们要知道大端字节序和小端字节序是什么意思

1.大端字节序(Big-Endian):在这种模式下,数据的高位字节保存在内存的低地址中,而数据的低位字节保存在内存的高地址中。这种排列方式与数据用字节表示时的书写顺序一致,符合人类的阅读习惯。大端字节序在网络传输和文件储存中较为常见。
2.小端字节序(Little-Endian):在这种模式下,数据的低位字节保存在内存的低地址中,而数据的高位字节保存在内存的高地址中。小端字节序与人类的阅读习惯相反,但更符合计算机读取内存的方式,因为CPU读取内存中的数据时,是从低地址向高地址方向进行读取的。

如何知道我们的程序是大端字节序还是小端字节序呢?可以通过下面这个代码

#include <stdio.h>
union{char byte[4];int num;
}test;int main()
{test.num=0x12345678;if(test.byte[0]==0x78)printf("小端\n");else if(test.byte[0]==0x12)printf("大端\n");elseprintf("error");printf("[0]:%p:0x%X\n""[1]:%p:0x%X\n""[2]:%p:0x%X\n""[3]:%p:0x%X\n",&test.byte[0], test.byte[0],&test.byte[1], test.byte[1],&test.byte[2], test.byte[2],&test.byte[3], test.byte[3]);
return 0;
}

我们在网络传输的时候用的是网络字节序,也就是大端字节序,进行网络通信时要把地址转化为大端字节序,下面是相关函数。

在这里插入图片描述
把点分十进制转化为大端字节序IP
在这里插入图片描述
把大端字节序IP转化为点分十进制IP
在这里插入图片描述

3.2 相关结构体和函数

常用的结构体sockaddr,我们一般用第二个结构体,方便我们赋值
在这里插入图片描述
这是我们用的socket函数

在这里插入图片描述
下面是它的参数说明在这里插入图片描述
成功以后会返回文件描述符

在这里插入图片描述
然后就是bind函数,用来给客户端和服务器端建立联系。

在这里插入图片描述
下面把客户端由注动变为监听状态(客户端主动连接服务器)

在这里插入图片描述

得到一个连接,进行客户端和服务端之间的通信

在这里插入图片描述
这里我们就用知道,accept是一个阻塞函数,它要从已连接队列中拿一个可用的连接过来。调用accept之前连接可能就已经建立了。

现在就可以连接服务器了,用connect函数

在这里插入图片描述

3.3 代码实现

服务端的开发

#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <ctype.h>int main()
{//创建socket//int socket(int domain, int type, int protocol);int lfd = socket(AF_INET, SOCK_STREAM, 0);if(lfd<0){perror("socket error");return -1;}//int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);//绑定struct sockaddr_in serv;bzero(&serv, sizeof(serv));serv.sin_family = AF_INET;serv.sin_port = htons(8888);serv.sin_addr.s_addr = htonl(INADDR_ANY); //表示使用本地任意可用IPint ret = bind(lfd, (struct sockaddr *)&serv, sizeof(serv));if(ret<0){perror("bind error");	return -1;}//监听//int listen(int sockfd, int backlog);listen(lfd, 128);//int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);struct sockaddr_in client;socklen_t len = sizeof(client);int cfd = accept(lfd, (struct sockaddr *)&client, &len);  //len是一个输入输出参数//const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);//获取client端的IP和端口char sIP[16];memset(sIP, 0x00, sizeof(sIP));printf("client-->IP:[%s],PORT:[%d]\n", inet_ntop(AF_INET, &client.sin_addr.s_addr, sIP, sizeof(sIP)), ntohs(client.sin_port));printf("lfd==[%d], cfd==[%d]\n", lfd, cfd);int i = 0;int n = 0;char buf[1024];while(1){//读数据memset(buf, 0x00, sizeof(buf));n = read(cfd, buf, sizeof(buf));if(n<=0){printf("read error or client close, n==[%d]\n", n);break;}printf("n==[%d], buf==[%s]\n", n, buf);	for(i=0; i<n; i++){buf[i] = toupper(buf[i]);}//发送数据write(cfd, buf, n);}//关闭监听文件描述符和通信文件描述符close(lfd);close(cfd);return 0;
}

客户端的开发

//客户端代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>int main()
{//创建socket---用于和服务端进行通信int cfd = socket(AF_INET, SOCK_STREAM, 0);if(cfd<0){perror("socket error");return -1;}//连接服务端//int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);struct sockaddr_in serv;serv.sin_family = AF_INET;serv.sin_port = htons(8888);inet_pton(AF_INET, "127.0.0.1", &serv.sin_addr.s_addr);printf("[%x]\n", serv.sin_addr.s_addr);int ret = connect(cfd, (struct sockaddr *)&serv, sizeof(serv));if(ret<0){perror("connect error");return -1;}	int n = 0;char buf[256];while(1){//读标准输入数据memset(buf, 0x00, sizeof(buf));n = read(STDIN_FILENO, buf, sizeof(buf));//发送数据write(cfd, buf, n);//读服务端发来的数据memset(buf, 0x00, sizeof(buf));n = read(cfd, buf, sizeof(buf));if(n<=0){printf("read error or server closed, n==[%d]\n", n);break;}printf("n==[%d], buf==[%s]\n", n, buf);}//关闭套接字cfdclose(cfd);return 0;
}

最后留下一个过程图
在这里插入图片描述

相关文章:

  • 07-Java桥接模式 ( Bridge Pattern )
  • PYthon进阶--网页采集器(基于百度搜索的Python3爬虫程序)
  • 引入BertTokenizer出现OSError: Can‘t load tokenizer for ‘bert-base-uncased‘.
  • G口大流量服务器选择的关键点有哪些?
  • arm 汇编积累
  • Java实现教学资源共享平台 JAVA+Vue+SpringBoot+MySQL
  • C语言第二十三弹---指针(七)
  • Android---PermissionX实现动态权限申请
  • vscode开发FPGA(0)--windows平台搭建
  • JS逆向进阶篇【去哪儿旅行登录】【上篇】
  • 意外删除照片数据?恢复照片数据的 10 大照片恢复工具方法
  • 2024/2/12 图的基础知识 2
  • 无人机飞行原理,多旋翼无人机飞行原理详解
  • 【国产MCU】-CH32V307-基本定时器(BCTM)
  • kali系统概述、nmap扫描应用、john破解密码、抓包概述、以太网帧结构、抓包应用、wireshark应用、nginx安全加固、Linux系统加固
  • 自己简单写的 事件订阅机制
  • __proto__ 和 prototype的关系
  • exif信息对照
  • HashMap剖析之内部结构
  • js递归,无限分级树形折叠菜单
  • Laravel 中的一个后期静态绑定
  • npx命令介绍
  • session共享问题解决方案
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 如何借助 NoSQL 提高 JPA 应用性能
  • 如何设计一个微型分布式架构?
  • 一个完整Java Web项目背后的密码
  • 译米田引理
  • 在Docker Swarm上部署Apache Storm:第1部分
  • 智能合约Solidity教程-事件和日志(一)
  • shell使用lftp连接ftp和sftp,并可以指定私钥
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • # Swust 12th acm 邀请赛# [ A ] A+B problem [题解]
  • #### go map 底层结构 ####
  • #define,static,const,三种常量的区别
  • #include
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • (a /b)*c的值
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (附源码)计算机毕业设计高校学生选课系统
  • (介绍与使用)物联网NodeMCUESP8266(ESP-12F)连接新版onenet mqtt协议实现上传数据(温湿度)和下发指令(控制LED灯)
  • (十)c52学习之旅-定时器实验
  • ***php进行支付宝开发中return_url和notify_url的区别分析
  • .dat文件写入byte类型数组_用Python从Abaqus导出txt、dat数据
  • .MSSQLSERVER 导入导出 命令集--堪称经典,值得借鉴!
  • .net framework 4.0中如何 输出 form 的name属性。
  • .net 程序发生了一个不可捕获的异常
  • .NET 设计模式—简单工厂(Simple Factory Pattern)
  • .NET单元测试
  • @entity 不限字节长度的类型_一文读懂Redis常见对象类型的底层数据结构
  • @德人合科技——天锐绿盾 | 图纸加密软件有哪些功能呢?
  • [ C++ ] STL_list 使用及其模拟实现
  • [ C++ ] template 模板进阶 (特化,分离编译)