浅谈python中的网络编程

初识CS构架,网络通信流程
1.CS架构 客户端服务端架构
服务端:提供服务的
客户端:享受服务的
2.BS架构:浏览器和服务端
3.网络通信流程:
集线器:将所有连接上它的电脑全部联通起来
交换机:升级版的集线器
网卡:接收处理电信号
Mac地址:网络设备的全球唯一标示,又称为物理地址
广播 单播
广播风暴
Ipv4地址:4个点分十进制 还有ipv6
作用:划分广播域
子网掩码:计算ip地址段,或者判断ip地址是否属于同一地址段
DHCP协议:自动获取ip地址
DNS:域名解析
Arp协议:通过ip地址获取mac,因为ip地址不固定,mac是全球唯一的
路由器:转发消息,管理内网
路由协议:计算路由转发的最优路径
端口:标示电脑上某个应用程序
Ip地址+端口 = 能够唯一锁定一台电脑和这个电脑上的某个应用程序
网关:把关用的,意思就说所有对外的请求都要经过网关
NAT技术:网络地址转换,内网ip地址转换为公网或者说外网的ip地址
模拟访问京东:

  流程描述:

  第一步:打开浏览器,想要请求访问京东,在地址栏输入了网址:www.jd.com。(www.jd.com是域名就是一个IP地址的名称,IP地址不好记,所有有了域名。)

  第二步:先将请求信息发给了交换机,然后交给了路由器,路由发给DNS服务器,通过DNS协议去找我们要访问的京东的IP地址:

  第三步:查到的京东服务器对应的IP地址之后,路由器通过路由协议找到一个路由转发的最优路径,将你的请求信息还送给这个IP地址的京东的路由器

  第四步:京东的路由器发给了京东网站的服务器上

  第五步:京东网站服务器按照来的时候的路径,在返回给你他自己的网站

  第六步:当你打开浏览器的时候,你的电脑给你的浏览器这个运行起来的程序给了一个编号,叫做端口号,当你的电脑收到京东发送过来的消息的时候,你的电脑                        通过端口号找到你的浏览器,你的浏览器拿到了京东的网站信息,然后将网站呈现在了自己的浏览器上

4.Socket:用于网络通信的模块,独立于语言

socket代码演示
socket服务端
 1 import socket  # 导入socket模块
 2 
 3 server = socket.socket()  # 创建一个socket对象
 4 ip_port = ('192.168.12.60', 8013)  # 给程序设置一个ip地址和端口号,买了个手机卡
 5 server.bind(ip_port)  # 绑定ip地址和端口,插卡
 6 server.listen()  # 监听ip地址和端口,简称开机
 7 coon, addr = server.accept()  # 等待建立连接, conn是连接通道,addr是客户端的地址,阻塞程序
 8 print('等待客户端链接' + '.' * 20)
 9 while 1:
10     try:
11         from_client_msg = coon.recv(1024)  # 服务端通过conn连接通道来收发消息,通过recv方法,recv里面的参数是字节(B),1024的意思1024B=1KB
12         if len(from_client_msg) == 0:  # 如果客户端不再传输数据,结束与该客户端的链接
13             print('对方已结束聊天')
14             break
15         print('德莱厄斯说:', from_client_msg.decode('utf-8'))  # 打印客户端消息
16         to_client_msg = input('贾克斯说:')  # 回复客户端
17         coon.send(to_client_msg.encode('utf-8'))  # 回复消息:通过send方法,参数必须是字节类型的,
18     except ConnectionResetError:  # 出现了客户端强制关闭链接情况,处理了报错
19         print('.' * 10 + '对方已下线' + '.' * 10)
20         break
21 coon.close()  # 关闭链接
22 server.close()  # 关闭server对象,关机

socket客户端:

 1 import socket                                   #导入socket
 2 client = socket.socket()                        #创建一个socket对象
 3 try:
 4     server_ip_port = ('192.168.12.60',8013)     #找到服务端的ip地址和端口
 5     client.connect(server_ip_port)              #连接服务端的应用程序,通过connect方法,参数是服务端的ip地址和端口,打电话
 6 except ConnectionResetError:                    #如果未找到该IP地址,则直接退出
 7     print('.'*10 + '该服务器未上线'+'.'*10)
 8     exit()
 9 while 1:
10     try:
11         to_server_msg = input('德莱厄斯说:')         #发消息
12         if to_server_msg == 'exit':
13             break
14         client.send(to_server_msg.encode('utf-8'))  #发消息,用的send方法,但是调用者是client的socket对象
15         from_server_msg = client.recv(1024)          #通过recv方法,recv里面的参数是字节(B),1024的意思1024B=1KB
16         print('贾克斯说',from_server_msg.decode('utf-8'))  #打印服务端消息
17     except ConnectionResetError:                    #如果服务端强行关闭,则退出
18         print('.' * 10 + '服务器宕机' + '.' * 10)
19         break
20 client.close()                                       #关闭链接
网络通信协议(TCP,UDP区别)
1.TCP UDP的区别 重点(*****)
   1.TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接

2.TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付

3.TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的

4.UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)

5.每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
 6.TCP对系统资源要求较多首部开销20字节;UDP对系统资源要求较少首部开销小
    7.TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道

2.TCP建立链接的三次握手:
1.首先客户端发送信息给服务端要建立链接.
2.服务方接到消息后反馈.
3.客户端收到反馈后向服务端发送确认连接.

   三次握手的官方解释:

  1. TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态;
  2. TCP客户进程也是先创建传输控制块TCB,然后向服务器发出连接请求报文,这是报文首部中的同部位SYN=1,同时选择一个初始序列号 seq=x ,此时,TCP客户端进程进入了 SYN-SENT(同步已发送状态)状态。TCP规定,SYN报文段(SYN=1的报文段)不能携带数据,但需要消耗掉一个序号。
  3. TCP服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该 ACK=1,SYN=1,确认号是ack=x+1,同时也要为自己初始化一个序列号 seq=y,此时,TCP服务器进程进入了SYN-RCVD(同步收到)状态。这个报文也不能携带数据,但是同样要消耗一个序号。
  4. TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,自己的序列号seq=x+1,此时,TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。TCP规定,ACK报文段可以携带数据,但是如果不携带数据则不消耗序号。
  5. 当服务器收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了。 

3.断开链接的四次挥手:
1.首先客户端给服务端发断开信息请求.
2.服务端收到请求后先反馈给客户端,让客户端等待处理未处理完的信息.
3.当服务端数据处理完毕后再发送信息给客户端表可以断开链接.
4.客户端收到后确认断开.

   四次挥手的官方解释:


      数据传输完毕后,双方都可释放连接。最开始的时候,客户端和服务器都是处于ESTABLISHED状态,然后客户端主动关闭,服务器被动关闭。服务端也可以主              动关闭,一个流程。


  1. 客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
  2. 服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
  3. 客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
  4. 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
  5. 客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
  6. 服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。
 
4.TCP/IP五层(或TCP/IP四层或OSI七层协议)
TCP/IP五层协议自下到上有物理层,数据链路层,网络层,传输层,应用层
TCP/IP四层协议自下到上有网络接口层,网络层,传输层,应用层
OSI七层协议自下到上有物理层,数据链路层,网络层,传输层,会话层,表示层,应用层

 下面这些协议简单知道一些常用的就行。(不是重点)

5.五层协议简介:
物理层:电信号,对应1(高电压)跟0(低电压)
数据链路层:以太网协议,单纯的0跟1没有意义,规定一组电信号来表示一个信息(加上了mac地址,源mac地址跟对方的mac地址),(最大1518个字节的head包含mac地址)
网络层(IP层):增加了IP协议,会增加上IP地址
传输层:存在TCP跟UDP两大协议,增加上端口号
应用层:初始化包装你最原始发送的信息(head,https协议)

socket在内的五层通讯流程

 

 
6.TCP与UDP下socket的区别:
1.TCP以字节流的形式传播(需要建立连接),UDP以包的形式传播(不需要建立连接)

TCP和UDP下socket差异对比图:

 


2.TCP传播的流程:
TCP服务端: TCP客户端:
创建套接字(socket) 创建套接字(socket)
绑定端口(bind)
侦听客户请求(listen)
接受客户链接(accept) 连接服务器(connect)
接收/发送(recv/send) 发送/接收(send/recv)
关闭套接字(closesocket) 关闭套接字(closesocket)

基于TCP的socket通讯流程图片:


3.UDP传播的流程:
UDP服务器(接收端): UDP客户端(发送端):
创建套接字(socket)
绑定端口(bind)
接收/发送(recvfrom/sendto) 发送/接收(sendto/recvfrom)
关闭套接字(closesocket) 关闭套接字(closesocket)

基于UDP的socket通讯流程:

 

7.UDP下的多人聊天:
UDP服务端:
 1 import socket
 2 
 3 udp_server = socket.socket(type=socket.SOCK_DGRAM) #datagram
 4 
 5 ip_port = ('127.0.0.1',8002)
 6 
 7 udp_server.bind(ip_port)
 8 
 9 while 1:
10 
11     from_client_msg, client_addr = udp_server.recvfrom(1024)
12 
13     print(from_client_msg.decode('utf-8'), client_addr)
14 
15     to_client_msg = input('服务端说:')
16     udp_server.sendto(to_client_msg.encode('utf-8'), client_addr)
17 
18 udp_server.close()
UDP客户端:
 1 import socket
 2 udp_client = socket.socket(type=socket.SOCK_DGRAM)
 3 ip_port = ('127.0.0.1',8002)
 4 
 5 while 1:
 6     to_server_msg = input('客户端说')
 7     udp_client.sendto(to_server_msg.encode('utf-8'), ip_port)
 8 
 9     from_server_msg, server_addr = udp_client.recvfrom(1024)
10     print(from_server_msg.decode('utf-8'), server_addr)
11 
12 udp_client.close()
好了,这一期的内容就这么多,如有问题的地方还请沟通,以供修正讨论.
 
 
 

 



 

 

 
posted @ 2019-01-03 22:44  Yeokrin  阅读(258)  评论(0编辑  收藏  举报