网络编程理论、socket初使用 第二十五天 2018.11.12
网络编程:---->C/S---->B/S
网络:网络是信息传输、接收、共享的虚拟平台,通过它把各个点、面、体的信息联系到一起,从而实现这些资源的共享。
软件开发的架构---->c/s架构、b/s架构
基于应用的网络程序 (应用类)---->qq 微信 飞秋 网游 微博 yy(APP、pc端软件)
基于浏览器的网络程序 (web类)---->百度 微博 知乎 博客园 网易 (浏览器、浏览器上的网页版)
网络编程中的 - C/S架构(c client 客户端 s server 服务端)
网络编程中的 - B/S架构(b browser 浏览器 s server 服务端)
不需要额外的安装客户端了,只需要一个网址就可以访问
轻量级 - 使用成本低
B/S架构是C/S架构的一种特殊形式
解耦分支思想---->一个大程序,分成多个小程序,可以用多门语言同时编写,最后统一所有入口
在不同机器上的两个py程序之间想要通信---->网络
网络的发展史
网卡\网线---->网卡提供插网线的接口
两台机器之间 插上网线就可以通信---->找到对方网卡
网卡上唯一的 ---- mac地址---->长度为48位2进制,通常由12位16进制数表示(前六位是厂商编号,后六位是流水线号)
ip地址:
规定网络地址的协议叫ip协议,它定义的地址称之为ip地址
编码、字节(8位2进制一断)
4个点分十进制 - ipv4协议
0.0.0.0 - 255.255.255.255(4个8位二进制数表示---->255)
127.0.0.1 本地的回环地址(一台机器上几个程序中的交流)
6个点分十进制 - ipv6协议
0.0.0.0.0.0 - 255.255.255.255.255.255
交换机---->多台机器之间的通信问题
广播 找所需要找的机器,会把查找信号传给所有机器 (绿色) 广播风暴:找机器信号过于庞大
单播 找到了机器给的反馈信号(红色)
组播
arp协议 : 通过IP地址获取对应机器的mac地址
每个局域网都有自己的网关---->局域网中的机器想要访问局域网外的机器,需要通过网关访问
子网掩码
子网掩码 和 ip地址进行 按位 与 运算 就能到网段地址
192.168.21.0 网段 在同一局域网内前三位一定相同(局域网的网段) 子网掩码 和 ip地址进行 按位 与 运算
网关地址 : 整个局域网中的机器能沟通过网关ip与外界通信

端口 : 0-65535 找到的要进行操作的程序
在计算机上每一个需要网络通信的程序,都会开一个端口
在同一时间只会有一个程序占用同一个端口
一台计算机上不可能在同一时间 有两个程序占用同一端口
端口范围:0-65535(前面端口计算机系统要使用)
一般情况下 8000之后的端口
ip---->确定唯一一台机器
端口---->确定唯一的一个程序
ip+端口---->找到唯一的一台机器上的唯一的一个程序
公网ip(在路由器上注册了)可以被其他人直接访问,内网ip不能对外提供服务
ip地址+端口号 : 在全网找到唯一的一台机器+唯一的应用
tcp协议
三次握手、四次握手
全双工的通信协议
一旦连接建立起来,那么连接两端的机器能够随意互相通信
数据安全不容易丢失
建立连接的 三次握手 ******
断开连接的 四次挥手 ******
TCP是因特网中的传输层协议,使用三次握手协议建立连接。当主动方发出SYN连接请求后,等待对方回答SYN+ACK[1],并最终对对方的 SYN 执行 ACK 确认。
这种建立连接的方法可以防止产生错误的连接。[1] TCP三次握手的过程如下: 客户端发送SYN(SEQ=x)报文给服务器端,进入SYN_SEND状态。 服务器端收到SYN报文,回应一个SYN (SEQ=y)ACK(ACK=x+1)报文,进入SYN_RECV状态。 客户端收到服务器端的SYN报文,回应一个ACK(ACK=y+1)报文,进入Established状态。 三次握手完成,TCP客户端和服务器端成功地建立连接,可以开始传输数据了。
建立一个连接需要三次握手,而终止一个连接要经过四次握手,这是由TCP的半关闭(half-close)造成的。 (1) 某个应用进程首先调用close,称该端执行“主动关闭”(active close)。该端的TCP于是发送一个FIN分节,表示数据发送完毕。 (2) 接收到这个FIN的对端执行 “被动关闭”(passive close),这个FIN由TCP确认。 注意:FIN的接收也作为一个文件结束符(end-of-file)传递给接收端应用进程,放在已排队等候该应用进程接收的任何其他数据之后,
因为,FIN的接收意味着接收端应用进程在相应连接上再无额外数据可接收。 (3) 一段时间后,接收到这个文件结束符的应用进程将调用close关闭它的套接字。这导致它的TCP也发送一个FIN。 (4) 接收这个最终FIN的原发送端TCP(即执行主动关闭的那一端)确认这个FIN。[1] 既然每个方向都需要一个FIN和一个ACK,因此通常需要4个分节。 注意: (1) “通常”是指,某些情况下,步骤1的FIN随数据一起发送,另外,步骤2和步骤3发送的分节都出自执行被动关闭那一端,有可能被合并成一个分节。[2] (2) 在步骤2与步骤3之间,从执行被动关闭一端到执行主动关闭一端流动数据是可能的,这称为“半关闭”(half-close)。 (3) 当一个Unix进程无论自愿地(调用exit或从main函数返回)还是非自愿地(收到一个终止本进程的信号)终止时,所有打开的描述符都被关闭,
这也导致仍然打开的任何TCP连接上也发出一个FIN。 无论是客户还是服务器,任何一端都可以执行主动关闭。通常情况是,客户执行主动关闭,但是某些协议,例如,HTTP/1.0却由服务器执行主动关闭。[2]

UDP协议:
当应用程序希望通过UDP与一个应用程序通信时,传输数据之前源端和终端不建立连接。
当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。
不可靠的,无连接的
快,不占连接
tcp---->打电话 udp---->发短信
QQ---->udp协议 在udp协议上自己完成了数据的检测
tcp---->TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。
udp---->UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。


套接字---->socket
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的
TCP/IP协议隐藏在Socket接口后面。
server端:(服务端)
import socket
sk = socket.socket() #创建客户套接字
#sk.bind(('ip','端口port')) #把地址绑定到套接字
sk.bind(('127.0.0.1',8080))
sk.listen() #监听链接
conn,addr = sk.accept() #接受客户端链接 conn---->connection链接 addr---->发消息人的地址
ret = conn.recv(1024) #接收客户端信息
print(ret) #打印客户端信息
conn.send(b'hi') #向客户端发送信息
ret = conn.recv(1024) #接收客户端信息
print(ret.decode('utf-8')) #打印客户端信息
conn.send(bytes('大碗油泼面'.encode('utf-8')))
conn.close() #关闭客户端套接字
sk.close() #关闭服务器套接字(可选)
'''
端口被占用或者端口暂时没关闭
#加入一条socket配置,重用ip和端口
import socket
from socket import SOL_SOCKET,SO_REUSEADDR
sk = socket.socket()
sk.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #就是它,在bind前加 避免服务重启的时候报address already use
sk.bind(('127.0.0.1',8898)) #把地址绑定到套接字
sk.listen() #监听链接
conn,addr = sk.accept() #接受客户端链接
ret = conn.recv(1024) #接收客户端信息
print(ret) #打印客户端信息
conn.send(b'hi') #向客户端发送信息
conn.close() #关闭客户端套接字
sk.close() #关闭服务器套接字(可选)
'''
client端:(客户端)
import socket
sk = socket.socket() # 创建客户套接字
sk.connect(('127.0.0.1',8080)) # 尝试连接服务器
sk.send(b'hello!')
ret = sk.recv(1024) # 对话(发送/接收)
print(ret)
sk.send(bytes('中午吃什么?'.encode('utf-8')))
ret=sk.recv(1024)
print(ret.decode('utf-8'))
sk.close() # 关闭客户套接字





浙公网安备 33010602011771号