python网络编程--socket,网络协议,TCP

. 客户端/服务端架构(用到网络通信的地方)

  我们使用qq、微信和别人聊天,通过浏览器来浏览页面、看京东的网站,通过优酷、快播(此处只是怀念一下)看片片啥的等等,通过无线打印机来打印一个word文档等,只要有无线、有网、有4G,我们就能好好的聊天,好好的看片片、好好的购物什么的,对吧,那么这些操作都叫做网络通信,确切来说都需要使用网络通信,前提是你要有网(大家记着这个'网',我下面会给大家详解),原来生活中处处使用了网络通信,我们通过网络通信的不同形式:比如说qq是我们下载到电脑或者手机上的应用程序(qq应用程序就是人家腾讯开发的软件,放到你的电脑或者手机上供你使用的,大概明白应用程序意思就行,不用深究~~),浏览器也是我们下载的应用程序,但是浏览器是通过页面来访问别人的网站的,而打印机我是通过我电脑上的word来操作使用的。根据这些不同的场景或者说不用的沟通方式,在业内划分了下面两个架构(架构:就是不同的组成结构)。在看下面的几个架构之前,我们需要知道什么是客户端,什么是服务端。客户端:安装在你电脑上的qq,浏览器(360浏览器、chrome浏览器、IE浏览器等),当我们使用qq发送消息的时候,消息先发送到了腾讯,然后腾讯在转发到你朋友的qq上,此时你的qq就是客户端,腾讯就是服务端。当我们使用浏览器来看京东的网站的时候,我们电脑上的浏览器就叫做客户端,京东就叫做服务端。

客户端英文名称:Client(使用服务端的服务),服务端英文名称:Server(一直运行着,等待服务别人,不能有一天访问百度,百度页面打不开,不行吧。),下面所说的C\S架构就是说的Client\Server架构。

    a.硬件C\S架构:打印机。

    b.软件C\S架构:QQ、微信、优酷、暴风影音、浏览器(IE、火狐,360浏览器等)。其中浏览器又比较特殊,很多网站是基于浏览器来进行访问的,浏览器和各个网站服务端进行的通讯方式又常被成为B\S架构(浏览器英文名称:Browser),web开发就是这个,后面大家知道有前端的课程对吧,前端就是浏览器上的知识,以后你会经常和浏览器打交道,学完前端就可以进行web开发全栈开发了。如果我把所有的东西都做成应用程序是不是很麻烦啊,要装很多的软件对吧,所有就开始有了B\S架构,只需要个浏览器就能使用很多的工具了,并且提供了一个统一入口,这也是为什么B\S架构火了起来。但是手机端的还是用的应用程序多一些,但是手机端B\S架构也是一个趋势,就像微信的小程序和公众号,为什么说是一个趋势呢,不仅仅是因为方便因为省钱,而是提供了一个统一的入口,其实微信早就实现了。统一入口是什么意思呢?就像我们公司经常用的一个公司内部管理系统,请假、打卡、报销、查客户等等,如果这些功能都需要打开一个网页或者app,是不是很难受啊,那么公司就做了这么一个系统,大家在这个系统上关于上班的一些你需要的功能就都能完成了,这就是统一入口。这也是一个开发思想,大程序分成几个小程序,开发速度也快,开发一个小功能就能上线,而不需要等着所有的功能全部开发完成才上线,解耦分治思想,公司做开发时这种思想很流行,迭代开发。

    不管哪个架构,他们都要进行网络通信,基本都要用socket,我们学习socekt就是为了完成C\S架构项目的开发

网关:

网关是一种充当转换重任的计算机系统或设备。

与网桥只是简单地传达信息不同,网关对收到的信息要重新打包,以适应目的系统的需求。同时,网关也可以提供过滤和安全功能。具体功能主要体现在以下几个方面:

1.具有协议转换功能。

2.具有流量控制和拥塞控制的能力。

3.具有在各个网络之间可靠传送信息的能力。

4.具有路由选择功能。

5.具有将分组分段和组装的能力。

集线器:

集线器的主要功能是对接收到的信号进行再生放大,以扩大网络的传输距离,同时把所有节点集中在以它为中心的节点上。集线器只是一个信号放大和中转的设备,它不具备交换功能。集线器能与网络中的打印服务器、交换机、文件服务器或其他的设备连接。它是一个标准的共享设备,不具备定向传送信号的能力

DNS过程

.网络通信的整个流程

端口+IP能够确定一台电脑上的某一个应用程序~~

  那么我们通过下面的代码简单看一下socket到底是个什么样子,大概怎么使用:下面的程序就是一个应用程序,和qq啊、微信啊是一样的,都叫做应用程序。

server服务器端:

# 导入import 模块

import socket
 
server = socket.socket() # 创建一个socket对象  (准备一个手机)
ip_port = ('192.168.12.34', 8001)  # 给程序设置一个ip地址和端口号  (买一个手机卡)
server.bind(ip_port) # 绑定ip地址和端口, (插卡) server.listen() # 监听ip地址和端口 (开机) conn,addr = server.acccept() # 等待建立连接,conn是连接通道,addr是客户端的地址 from_client_msg = conn.recv(1024) # 服务端通过conn连接通道来收发消息,通过recv方法来接收,参数是字节(B) print(from_client_msg) conn.send(b'123') # 通过conn管道的send方法发送消息,参数必须是字节类型的 conn.close() #关闭通道,close()方法 server.close() # 关闭socket对象 (关机)

 

client客户端:

# client客户端

import socket  # 引入socket模块

 

client = socket.socket()  # 创建socket对象
server_port = ('192.168.12.34',8001)  # 找到服务器的ip地址和端口

client.connect(server_port)  # 连接服务器的应用程序,通过connect方法,参数是服务器端的ip地址和端口

client.send(b'123')  # 发送信息,调用者是client的socket对象
from_server_msg = client.recv(1024)  # 接收信息
print(from_server_msg)

client.close()  # 关闭对象

注意:先运行server,然后再运行client,然后你会发现client这个文件再输出台的地方让你输入内容,你输入一个内容然后回车,你会发现server那边的控制台就输出了以client发送的内容

. 网络通讯协议

tcp头:

 

  位码即tcp标志位,标志位字段(U,A,P,R,S,F):占6比特, 含义如下:

    •   SYN(synchronous建立联机):发起一个链接      
    •   ACK(acknowledgement 确认):确认信号有效         
    •   PSH(push传送):接收方应该尽快将这个报文段交给应用层
    •   FIN(finish结束) :释放一个连接              
    •   RST(reset重置):重建连接                   
    •   URG(urgent紧急):紧急指针有效
    •   Sequence number(顺序号码)     
    •   Acknowledge number(确认号码).

 

1.tcpudp的区别

  TCP---传输控制协议,提供的是面向连接、可靠的字节流服务。  

  当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。   

  UDP---用户数据报协议,是一个简单的面向数据报的运输层协议。

  不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快

 

 

四. socket 

1.tcp 和 udp 下的socket

允许地址重用时需要加这一行代码

import socket

from socket import SOL_SOCKET,SO_REUSEADDR
sk = socket.socket()

# sk.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #允许地址重用

 

 udp下的服务端与客户端

客户端:

import socket # 引入模块

# 创建udp对象
udp_client = socket.socket(type = socket.SOCK_DGRAM)

# 指定ip地址和端口
ip_port = ('127.0.0.1', 8001)

# 发送消息
udp_client.sendto(b'hello',ip_port)

# 解包消息
from_server_msg,sever_addr = udp_client.recvfrom(1024)

# 打印消息
print(from_server_msg)

服务端:

import socket  # 引包

 
# 创建socket对象
udp_server = socket.socket(type=socket.SOCK_DGRAM)

# 指定ip地址
ip_port = ('127.0.0.1', 8001)

# 绑定ip地址
udp_server.bind(ip_port)

# 解构接收到的消息
from_client_msg, client_addr = udp_server.recvfrom(1024)

# 发送消息
udp_server.sendto(b'you too', client_addr)

# 打印消息
print(from_client_msg) 

 

2.socket方法

套接字格式:

socket(family,type[,protocal]) 使用给定的地址族、套接字类型、协议编号(默认为0)来创建套接字。

socket类型

 

socket函数

1.TCP发送数据时,已建立好TCP连接,所以不需要指定地址。UDP是面向无连接的,每次发送要指定是发给谁。

2.服务端与客户端不能直接发送列表,元组,字典。需要字符串化repr(data)。

 

 

 

. DNS解析及过程

域名: www.baidu.com

三级域名.二级域名.顶级域名

 

DNS域名服务器

  1. 根域名服务器: 最高层次的域名服务器,一共只有13个,许多国家都安装了根域名服务器的镜像服务器(这些服务器使用了任播技术,ip地址相同,ip数据报交付最近的一台处理)
  2. 顶级域名服务器(TLD服务器):管理在这个服务器注册的所有耳机域名
  3. 权限域名服务器:负责一个区的域名服务器
  4. 本地域名服务器

 

步骤1:

  1. 主机向本地域名服务器查询(递归查询),在本机向本地服务器查询时,属于递归查询
  2. 向根服务器查询(迭代查询),在本地服务器向外网查询时,属于迭代查询

 

 

 

  第一步:客户机提出域名解析请求,并将该请求发送给本地的域名服务器.
  第二步:当本地的域名服务器收到请求后,就先查询本地的缓存,如果有该纪录项,则本地的域名服务器就直接把查询的结果返回.
  第三步:如果本地的缓存中没有该纪录,则本地域名服务器就直接把请求发给根域名服务器,然后根域名服务器再返回给本地域名服务器一个所查询域(根的子域)的主域名服务器的地址.
  第四步:本地服务器再向上一步返回的域名服务器发送请求,然后接受请求的服务器查询自己的缓存,如果没有该纪录,则返回相关的下级的域名服务器的地址.
  第五步:重复第四步,直到找到正确的纪录.
  第六步:本地域名服务器把返回的结果保存到缓存,以备下一次使用,同时还将结果返回给客户机.
  让我们举一个例子来详细说明解析域名的过程.假设我们的客户机如果想要访问站点:www.linejet.com此客户本地的域名服务器是dns.company.com , 一个根域名服务器是NS.INTER.NET , 所要访问的网站的域名服务器是dns.linejet.com,域名解析的过程如下所示.
  (1)客户机发出请求解析域名www.linejet.com的报文
  (2)本地的域名服务器收到请求后, 查询本地缓存, 假设没有该纪录, 则本地域名服务器dns.company.com则向根域名服务器NS.INTER.NET发出请求解析域名www.linejet.com
  (3)根域名服务器NS.INTER.NET收到请求后查询本地记录得到如下结果:linejet.com NS dns.linejet.com (表示linejet.com域中的域名服务器为:dns.linejet.com ), 同时给出dns.linejet.com的地址,并将结果返回给域名服务器dns.company.com
  (4)域名服务器dns.company.com 收到回应后,再发出请求解析域名www.linejet.com的报文.
  (5)域名服务器 dns.linejet.com收到请求后,开始查询本地的记录,找到如下一条记录:www.linejet.com A 211.120.3.12 (表示linejet.com域中域名服务器dns.linejet.com的IP地址为:211.120.3.12),并将结果返回给客户本地域名服务器dns.company.com
  (6)客户本地域名服务器将返回的结果保存到本地缓存,同时将结果返回给客户机.
  这样就完成了一次域名解析过程.

posted @ 2019-01-02 17:14  robertx  阅读(262)  评论(0编辑  收藏  举报