一、客户端/服务器架构

1.硬件C/S架构(打印机)

打印机作为一个服务端,电脑连接打印机进行打印

2.软件C/S架构

  互联网中处处是C/S架构

  如谷歌网站是服务端,你的浏览器是客户端(B/S架构也是C/S架构的一种)

  腾讯作为服务端为你提供视频,你得下个腾讯视频客户端才能看它的视频)

C/S架构与socket的关系:

我们学习socket就是为了完成C/S架构的开发

二、什么是tcp/ip协议

​ 计算机之间通讯需要遵循一定的互联网协议,比如tcp/ip协议,大量的计算机之间进行通讯组成了计算机网络,网络的核心即一堆协议,协议即标准,由于tcp/ip协议太过于复杂,这时需要用socket层对tcp/ip协议进行精简,提供相应的接口以便更加方便的调用。所以学习socket一定要先学习互联网协议。

互联网协议按照功能不同分为osi七层或tcp/ip五层或tcp/ip四层

每层运行常见物理设备

TCP/IP 是一类协议系统,它是用于网络通信的一套协议集合,传统上来说 TCP/IP 被认为是一个四层协议。

1) 网络接口层:

物理层:主要是指物理层次的一些接口,比如电缆等.

提供计算机互通的物理介质, 基于电器特性发送高低电压(电信号),高电压对应数字1,低电压对应数字0

数据链路层:

定义电信号的分组方式,使用以太网协议封装数据格式(数据报头(18个字节双方地址+数据类型)+数据)

2) 网络层:

提供独立于硬件的逻辑寻址,实现物理地址与逻辑地址的转换.

在 TCP / IP 协议族中,网络层协议包括 IP 协议(网际协议),ICMP 协议( Internet 互联网控制报文协议),以及 IGMP 协议( Internet 组管理协议).

网络层引入一套新的地址用来区分不同的广播域/子网,这套地址即网络地址(IPV4/IPV6)

3) 传输层:

为网络提供了流量控制,错误控制和确认服务.

在 TCP / IP 协议族中有两个互不相同的传输协议: TCP(传输控制协议)和 UDP(用户数据报协议).

建立端口到端口的通信(应用软件使用的端口号)。

4) 应用层:

为网络排错,文件传输,远程控制和 Internet 操作提供具体的应用程序

数据包在 TCP / IP 协议中数据先由上往下将数据装包,然后由下往上拆包

在装包的时候,每一层都会增加一些信息用于传输,这部分信息就叫报头,当上层的数据到达本层的时候,会将数据加上本层的报头打包在一起,继续往下传递.

在拆包的时候,每一层将本层需要的报头读取后,就将剩下的数据往上传.

这个过程有点像俄罗斯套娃,所以有时候人们也会用俄罗斯套娃来形容这个过程.

tcp的三次握手四次挥手

三次握手:1.客户端对服务端发送同步请求(建立连接通道);2.服务端响应后,发送同步请求(建立连接通道)和发送确认数据(这里的两个请求被合并成一个了);3.客户端向服务端发送确认数据。

四次挥手:1.客户端发送端口结束包给服务端,2.服务端收到以后返回确认信息给客户端;3.服务端发送端口结束包给客户端;4.客户端确认信息返回给服务端。

区别:四次挥手的过程中,服务端返回给客户端的确认信息之后不会立刻关闭,有可能会继续给客户端发送数据,所以必须得有四次挥手

三、socket是什么

Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

所以,我们无需深入理解tcp/udp协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵循tcp/udp标准的。

没有socket之前

有socket之后

为什么socket翻译为套接字?

socket中文翻译为套接字,socket英文本义为孔和插座的意思。

套接字发展史及分类

套接字起源于 20 世纪 70 年代加利福尼亚大学伯克利分校版本的 Unix,即人们所说的 BSD Unix。 因此,有时人们也把套接字称为“伯克利套接字”或“BSD 套接字”。一开始,套接字被设计用在同 一台主机上多个应用程序之间的通讯。这也被称进程间通讯,或 IPC。套接字有两种(或者称为有两个种族),分别是基于文件型的和基于网络型的。

*基于文件类型的套接字家族*

套接字家族的名字:AF_UNIX

unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信

*基于网络类型的套接字家族*

套接字家族的名字:AF_INET

还有AF_INET6被用于ipv6,还有一些其他的地址家族,所有地址家族中,AF_INET是使用最广泛的一个,python支持很多种地址家族.

*family(socket家族)*

  • socket.AF_UNIX:用于本机进程间通讯,为了保证程序安全,两个独立的程序(进程)间是不能互相访问彼此的内存的,但为了实现进程间的通讯,可以通过创建一个本地的socket来完成

  • socket.AF_INET:(还有AF_INET6被用于ipv6,还有一些其他的地址家族,不过,他们要么是只用于某个平台,要么就是已经被废弃,或者是很少被使用,或者是根本没有实现,所有地址家族中,AF_INET是使用最广泛的一个,python支持很多种地址家族,但是由于我们只关心网络编程,所以大部分时候我么只使用AF_INET)

*socket type类型*

  • socket.SOCK_STREAM #for tcp

  • socket.SOCK_DGRAM #for udp

  • socket.SOCK_RAW #原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。

  • socket.SOCK_RDM #是一种可靠的UDP形式,即保证交付数据报但不保证顺序。SOCK_RAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,如发送ICMP报文。SOCK_RAM通常仅限于高级用户或管理员运行的程序使用。

  • socket.SOCK_SEQPACKET #废弃了

套接字工作流程

一个生活中的场景。你要打电话给一个朋友,先拨号,朋友听到电话铃声后提起电话,这时你和你的朋友就建立起了连接,就可以讲话了。等交流结束,挂断电话结束此次交谈。 生活中的场景就解释了这工作原理。

​ 服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束.

socket函数

服务端套接字函数

  • s.bind() 绑定(主机,端口号)到套接字

  • s.listen() 开始TCP监听

  • s.accept() 被动接受TCP客户的连接,(阻塞式)等待连接的到来

客户端套接字函数

  • s.connect() 主动初始化TCP服务器连接

  • s.connect_ex() connect()函数的扩展版本,出错时返回出错码,而不是抛出异常

公共用途的套接字函数

  • s.recv() 接收数据

  • s.send() 发送数据(send在待发送数据量大于己端缓存区剩余空间时,数据丢失,不会发完,可后面通过实例解释)

  • s.sendall() 发送完整的TCP数据(本质就是循环调用send,sendall在待发送数据量大于己端缓存区剩余空间时,数据不丢失,循环调用send直到发完)

  • s.sendto() 发送UDP数据

  • s.recvfrom()接收UDP数据 Receive data from the socket. The return value is a pair (bytes, address)

  • s.getpeername() 连接到当前套接字的远端的地址

  • s.close() 关闭套接字

  • socket.setblocking(flag) #True or False,设置socket为非阻塞模式,以后讲io异步时会用

  • socket.getaddrinfo(host, port, family=0, type=0, proto=0, flags=0) 返回远程主机的地址信息,例子 socket.getaddrinfo('google.com',80)

  • socket.getfqdn() 拿到本机的主机名

  • socket.gethostbyname() 通过域名解析ip地址

  • s.getsockopt() 返回指定套接字的参数

  • s.setsockopt() 设置指定套接字的参数

面向锁的套接字方法

  • s.setblocking() 设置套接字的阻塞与非阻塞模式

  • s.settimeout() 设置阻塞套接字操作的超时时间

  • s.gettimeout() 得到阻塞套接字操作的超时时间

面向文件的套接字的函数

  • s.fileno() 套接字的文件描述符

  • s.makefile() 创建一个与该套接字相关的文件

参考链接

[1]https://blog.csdn.net/yulyu/article/details/69062288

[2]https://www.zhihu.com/question/21383903

Python之路(第三十篇) 网络编程:socket、tcp/ip协议的更多相关文章

  1. Python之路(第三十三篇) 网络编程:socketserver深度解析

    一.socketserver 模块介绍 socketserver是标准库中的一个高级模块,用于网络客户端与服务器的实现.(version = "0.4") 在python2中写作S ...

  2. Python之路(第三十一篇) 网络编程:简单的tcp套接字通信、粘包现象

    一.简单的tcp套接字通信 套接字通信的一般流程 服务端 server = socket() #创建服务器套接字 server.bind() #把地址绑定到套接字,网络地址加端口 server.lis ...

  3. 嵌入式linux的网络编程(1)--TCP/IP协议概述

    嵌入式linux的网络编程(1)--TCP/IP协议概述 1.OSI参考模型及TCP/IP参考模型 通信协议用于协调不同网络设备之间的信息交换,它们建立了设备之间互相识别的信息机制.大家一定都听说过著 ...

  4. android 网络编程--socket tcp/ip udp http之间的关系

    网络七层由下往上分别为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层,一般编程人员接触最多的就是应用层和运输层,再往下的就是所谓的媒体层了,不是我们研究的对象. 下面是应用层.运输层,网络 ...

  5. Python之路(第三十七篇)并发编程:进程、multiprocess模块、创建进程方式、join()、守护进程

    一.在python程序中的进程操作 之前已经了解了很多进程相关的理论知识,了解进程是什么应该不再困难了,运行中的程序就是一个进程.所有的进程都是通过它的父进程来创建的.因此,运行起来的python程序 ...

  6. java 网络编程基础 TCP/IP协议:服务端ServerSocket;客户端Socket; 采用多线程方式处理网络请求

    1.Java中客户端和服务器端通信的简单实例 Java中能接收其他通信实体连接请求的类是ServerSocket,ServerSocket对象用于监听来自客户端的Socket连接,如果没有连接,它将一 ...

  7. Python之路【第二十篇】:待更新中.....

    Python之路[第二十篇]:待更新中.....

  8. Python之路【第十篇】:HTML -暂无等待更新

    Python之路[第十篇]:HTML -暂无等待更新

  9. Python之路【第六篇】:socket

    Python之路[第六篇]:socket   Socket socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字&quo ...

随机推荐

  1. Spring Boot探究之旅--启动分析

    刚接触SpringBoot,感觉挺方便的,不用配置那么多乱七八糟的配置,很方便!酒饱思淫欲,得陇望蜀一下,看看SpringBoot到底怎么做到这么方便的. 首先呢,先来看个SpringBoot的hel ...

  2. python中定时任务

    今天看网络框架时,突然想看一下定时器,于是往上搜索了一下python中timer task的实现,但是由于python本身对线程的支持不是太好,因为全局排它锁的存在,使得多线程在访问资源时效率比较低. ...

  3. django之两个使用模板的例子

    from django.db import models # Create your models here. class Book(models.Model): title=models.CharF ...

  4. RF:操作笔记

    1.变量运算

  5. SpringBoot 之静态资源

    boot 的默认的静态资源有多个, 由 ResourceProperties 配置了默认值: private static final String[] CLASSPATH_RESOURCE_LOCA ...

  6. python解决open()函数、xlrd.open_workbook()函数文件名包含中文,sheet名包含中文报错的问题

    问题现象: 1.使用open()函数.xlrd.open_workbook()函数打开文件,文件名若包含中文,会报错找不到这个文件或目录. 2.获取sheet时若包含中文,也会报错. #打开文件 fi ...

  7. <记录> curl 封装函数

    1. POST请求 参数1 : 请求地址 参数2 : 数组形式的参数 /** * @param string $url post请求地址 * @param array $params * @retur ...

  8. python批量处理文件夹中文件的问题

    用os模块读取文件夹中文件 原来的代码: import osfrom scipy.misc import imread filenames=os.listdir(r'./unprocess')for ...

  9. Linux网络编程学习计划

    由于网络编程是很重要的一块,自己这一块也比较欠缺,只知道一些皮毛,从今天开始系统学习<Linux网络编程>一书,全书分为十四个章节: 第一章   概论   P1-16 第二章   UNIX ...

  10. 使用jQuery+huandlebars遍历if判断不足引用helper

    兼容ie8(很实用,复制过来,仅供技术参考,更详细内容请看源地址:http://www.cnblogs.com/iyangyuan/archive/2013/12/12/3471227.html) & ...