网络,TCP/IP,三次握手,四次挥手,UDP,发邮件
OSI七层网络模型
也有说“五层协议”,就是将应用层,表示层,会话层统称 “ 应用层 ”
TCP/IP
三次握手(连接过程)
-
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。
-
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
-
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
四次挥手(断开过程)
-
主机A发送断开TCP连接请求的报文,其中报文中包含seq序列号,是有发送端随机生成的,并且还将报文中FIN字段的值设为1,表示需要断开TCP连接。
-
主机B会回复A发送的TCP断开请求报文,其中包含seq序列号,是由恢复段随机生成的,而且会产生ACK字段,ACK字段的数值,是在A发送过来的seq序列号基础上加1进行回复的,以便A收到信息时,知晓自己的TCP断开请求已得到了验证。
-
在主机B回复完A的TCP断开请求后,不会马上就进行TCP连接的断开,主机B先会确认确保断开前,所有传输到A的数据是否已经传输完毕,一旦确认传输完毕就会将回复报文的FIN字段置为1,并产生随机seq序列号。
-
主机A收到主机B的TCP断开请求后,会回复主机B 的断开请求,包含随机生成的seq字段和ack字段,ack字段会在主机B的TCP断开请求的seq的基础上加1,从而完成主机B请求的验证回复。
客户端
-
创建socket对象
socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
参数一:指定的ip协议: AF_INET指定使用ipv4协议,若要使用IPV6则指定为AF_INET6
参数二:SOCK_STREAM指定使用面向流的TCP协议 -
创建连接
客户端要主动发起TCP连接必须知道服务器的IP地址和端口号
sock.connect((“www.zxxk.com”,80))
address地址,以元组的形式传递: (域名/ip地址 , 端口号)
端口号小于1024的是Internet标准服务端口,大于1024的可以随意使用
网页的端口 80
STMP服务端口 25 -
发送请求
sock.send(b’你要发送的内容’)
要求发送的数据必须是二进制的 -
代码片段
服务端
-
服务器进程需要先绑定一个端口并且监听来自其他客户端的链接,如果某个客户端链接过来了,服务器就与该客户端建立socket链接,之后的通讯就依赖于这个socket
-
因为一台服务器可以响应多个客户端的请求,这样若是来标识唯一的一个socket,则依赖下面四项:服务器地址,服务器端口,客户端地址,以及客户端端口。
-
还有,因为服务器需要同时响应请求,所以,每个连接都需要开启一个新的线程来处理,否则服务器一次就只能服务一个客户端了。
-
代码片段
UDP
-
TCP是,建立可靠的连接,并且通讯双方都可以以流的形式发送数据,相对于TCP,UDP则是面向无连接的协议。
-
使用UDP协议时,不需要建立连接,只需要知道对方的IP地址和端口号,就可以直接发送数据包,但是能不能到达就不知道了
-
优点:速度快,对于不要求可靠到达的数据,就可以使用UDP协议
-
缺点:不可靠
-
代码片段:
发邮件
以163邮箱为例:
-
登录163邮箱 --> 设置 —>POP3/SMTP/IMAP --> 客户端授权密码 --> 开启 --> 重置授权码
-
打开服务连接 --> 登录邮箱–> 发送邮件–> 退出邮箱
#发邮件的库 import smtplib #邮件文本 from email.mime.text import MIMEText #SMTP服务器 SMTPServer = 'smtp.163.com' #发邮箱的地址 sender = 'xxxxx@163.com' #发送者授权码" password = 'xxxxxx' #设置发送文本的内容 message = 'hello world' #转为邮件文本 msg = MIMEText(message) #标题 msg['Subject'] = '这个是邮件的标题' #发送者 msg['From'] = sender #收件人 msg['To'] ='xxx@163.com' #打开SMTP服务器,端口号一般为25 mailServer = smtplib.SMTP(SMTPServer,25) #登录邮箱 mailServer.login(sender,password) #发送邮件 mailServer.sendmail(sender,['xxx@163.com'],msg.as_string()) #退出邮箱 mailserver.quit()