python网络编程

软件开发架构

C/S架构(客户端/服务器端)
client请求服务,server等待服务别人
B/S架构(浏览器端/服务器端)
浏览器browser

实现通信网卡和网线
网卡上有世界上唯一的mac地址,48位2进制

计算机8位一断句
编号
4个点分十进制
00000000.00000000.00000000.00000000
最多全为1,最大255
0.0.0.0-255.255.255.255 这个协议为ip协议,ipv4
ipv6 0.0.0.0.0.0-255.255.255.255.255.255
IP地址
通过IP地址找到mac地址,遵循的是ARP协议

以太网:局域网与交换机

交换机解决多台电脑的通信问题
交换机如何通信:发出信号广播,回应单播
数据网络中允许广播,被限制在二层交换机的局域范围内,禁止广播数据穿过路由器,防止广播数据影响大面积主机

AEP协议:地址解析协议,根据IP地址获取物理地址的一个TCP/IP协议
主机发送信息时将包含目标ip地址的arp请求广播到网络上所有主机,并接受返回消息,以此确定目标物理地址。
收到消息后将该IP地址和物理地址存入本机arp缓存中并保留一定时间,下次请求时直接查询arp缓存以节约资源。

机器多出现广播风暴

广域网与路由器

路由器,连接因特网中各局域网、广域网设备
网关:局域网中的机器想要访问局域网外的机器通过网关访问

怎么知道这个机器和要访问的机器在不在同一个网络里
IP地址和子网掩码按位与
IP地址:192.168.13.253
子网掩码:255.255.255.0
11111111.11111111.11111111.00000000

填位法

128,64,32,16,8,4,2,1
192-168=64 11000000
168-128=40 40-32=8 10101000
13 -8 = 5 5-4 =1 00001101
253与255差了2 11111101
因此,IP地址为:110000000.10101000.00001101.11111101
11111111.11111111.11111111.00000000
110000000.10101000.00001101.11111101

=110000000.10101000.00001101,00000000
192.168.13.0 网段
前三位与网段相同就是在同一个网络里

IP协议的作用主要有两个:一是为每一台计算机分配IP地址,另一个是确定那些地址在同一个网络。

找到机器后通过端口找程序
在计算机上每一个需要联网的程序都会开一个端口
在同一时间只会有一个程序占用一个端口,不可能在同一时间,同一计算机上有两个程序占用同一个端口
端口范围:0-65535
8000之后端口,一般用的时候
如果有IP确定唯一一台机器,端口确定唯一程序
ip+端口,唯一机器上唯一程序

127.0.0.1 本地回环地址,代表自己一台机器两个程序在通信

TCP协议,UDP协议

程序之间通信,TCP协议
全双工 :双方都可以收发信息。

  1. 建立TCP连接,也就是通过三报文握手来建立TCP连接。
  2. 数据传送,也就是基于已建立的TCP连接进行可靠的数据传输。
  3. 释放连接,也就是在数据传输结束后,还要通过四报文挥手来释放TCP连接。

连接过程 :三次握手
客户端发起连接,服务器端分配资源响应,并询问客户端可以是否可以连接,客户端响应,同意。
python网络编程_第1张图片
数据传输:每一次传输都会确认是否收到
可靠的,面向连接的,且传递过程中全双工的
一旦连接就一直连接,直到断开
TCP 四次挥手关闭连接
由于TCP连接是全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。
python网络编程_第2张图片

为什么连接的时候是三次握手,关闭的时候却是四次挥手?
TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议,TCP是全双工模式。这就意味着,关闭连接时,当Client端发出FIN报文段时,只是表示Client端告诉Server端数据已经发送完毕了。当Server端收到FIN报文并返回ACK报文段,表示它已经知道Client端没有数据发送了,但是Server端还是可以发送数据到Client端的,所以Server很可能并不会立即关闭SOCKET,直到Server端把数据也发送完毕。当Server端也发送了FIN报文段时,这个时候就表示Server端也没有数据要发送了,就会告诉Client端,我也没有数据要发送了,之后彼此就会愉快的中断这次TCP连接。

UDP协议
传输数据之前源端和终端不建立连接
想传送数据时就直接抓取来自应用程序的的数据,并尽可能快的把他扔到网络上。
不可靠
tcp和udp对比
TCP传输控制协议,提供面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个Tcp连接,之后才能传输。TCP超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传输到一端。
UDP用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,只是把IP数据报送出去,不能保证到达目的地,不建立连接速度快。

互联网协议

python网络编程_第3张图片

python网络编程_第4张图片
本身没有层级限制,人为的分层
写代码在应用层写
每层运行的常用设备
物理层:中继器,集线器,双绞线
数据链路层:网桥,以太网交换机,网卡 arp协议
网络层:路由器(三层),三层交换机:带路由功能的交换机 IP协议
传输层:四层交换机,四层路由器 TCP/UDP协议

Socket(套接字)python网络编程_第5张图片

Socket应用层与TCP/IP协议族通信的中间软件抽象层,接口,把复杂的TCP/IP协议族隐藏在Socket接口后面。调用模块,建立两个进程之间的连接和通信。

基于文件类型套接字家族 AF_UNIX
基于网络类型的套接字家族AF_INET ipv4

文件传输都走TCP协议:Web浏览器、电子邮件、文件传输程序
UDP:域名系统、视频流、ip语音python网络编程_第6张图片
现有服务端

#TCP连接
server.py
import socket
sk = socket.socket()
sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)#避免服务器重启时报addres,already in use
#sk.bind(('ip','port')) #绑定ip和端口号
sk.bind(('127.0.0.1',8080))
sk.listen() #监听,等着连接
conn,addr = sk.accept()#接收别人的连接请求,connection 连接,address地址(别人的地址)
ret = conn.recv(1024)#接收数据
#接收到中文后 ret=conn.recv(1024)
#ret.decode('utf-8')
print(ret)
conn.send(b'hi') #发送数据,必须传bytes类型
conn.close() #关闭连接
sk.close()#关闭程序

client.py
import socket
sk = socket.socket()#对象
sk.connect(('127.0.0.1',8080))#连接服务器的地址和端口,已经建立连接
sk.send(b'hello')
#中文 sk.send(bytes('中午吃什么'.encode('utf-8')))
ret = sk.recv(1024)
print(ret)
sk.close()

有收必有发
带有循环的例子:启动过程中先启动服务器端,断开过程中,先断开客户端

#server.py
import socket
sk = socket.socket()
sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sk.bind(('127.0.0.1',8080))
sk.listen()
conn , addr = sk.accept()# 接收连接,和地址端口
print(addr)
print('成功连接')
while True:
    ret = conn.recv(1024).decode('utf-8') #接收消息
    print(ret)
    if ret == 'bye':
        conn.send(b'bye')
        break
    input_con = input('>>>')
    conn.send(bytes(input_con,encoding='utf-8'))
    
conn.close()
sk.close()
#client.py
import socket
sk = socket.socket()
sk.connect(('127.0.0.1',8080))
while True:
    input_con = input(">>>")
    sk.send(bytes(input_con,encoding='utf-8'))
    ret = sk.recv(1024).decode('utf-8')#接收消息
    print(ret)
    if ret =='bye':
        sk.send(b'bye')
        break
sk.close()

练习:
服务器端接收时间戳,转换成格式化时间
客户端每隔十秒,把时间戳时间发给server

#server.py
import socket
import time

sk = socket.socket()
sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sk.bind(('127.0.0.1',8080))
sk.listen()
conn , add = sk.accept()
print('连接成功')
while True:
	ret = conn.recv(1024).decode('utf-8')
	timearray = time.localtime(float(ret))
	formattime = time.strftime("%Y-%m-%d %H:%M:%S",timearray)
	print(formattime)
conn.close()
sk.close()
#client.py
import socket
import time

sk = socket.socket()
sk.connect(('127.0.0.1',8080))
while True:
	now_time = time.time()
	print(now_time)
	sk.send(bytes(str(now_time),encoding='utf-8'))
	time.sleep(10)
sk.close()


你可能感兴趣的:(Python,网络,python)