1. UDP总结
使用udp发送/接收数据步骤:
1. 创建客户端套接字
2. 发送/接收数据
3. 关闭套接字
import socket
def main():
# 1. 创建udp套接字
# socket.AF_INET 表示IPV4协议,AF_INET6表示IPv6协议
# socket.SOCK_DGRAM 数据报套接字,只要用于udp协议
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
# 2. 准备接收方的地址
# 元组类型 ip是字符串类型 端口号是整型
dest_addr = ('192.168.113.111',8888)
# 要发送的数据
send_data = '我是要发送的数据'
# 3. 发送数据
udp_socket.sendto(send_data.encode('utf-8'),dest_addr)
# 4. 等待接收方发送的数据,如果没有接收到数据则会阻塞等待,知道收到数据
# 接收到的数据是一个元组 (接收到的数据,发送方的ip和端口)
# 1024 表示本次接收的最大字节数
recv_data,addr = udp_scoket.recvfrom(1024)
# 5. 关闭套接字
udp_socket.close()
if __name__ == '__main__':
main()
udp 绑定端口号:
1. 创建socket 套接字
2. 绑定端口号
3. 接收/发送数据
4. 关闭套接字
import socket
def main():
# 1. 创建udp套接字
# socket.AF_INET 表示 IPv4 协议 AF_INET6 表示IPv6协议
# socket.SOCK_DGRAM 数据报套接字,只用用于udp协议
udp_socket = socket.socket(socket.AF_INEF,socket.SOCK_DGRAM)
# 2. 绑定端口
# 元组类型 ip一般不写,表示本机的任何的一个ip
local_addr = ("",7777)
udp_socket.bind(loacl_addr)
# 3. 准备接收方的地址
# 元组类型, ip 是字符串类型 端口号是整型
dest_addr = ('192.168.113.111',8888)
# 要发送的数据
send_data = '我是要发送的数据'
# 4. 发送数据
udp_socket.sendto(send_data.encode('utf-8'),dest_addr)
# 5. 等待接收方发送的数据 如果没有收到数据则会阻塞等待,知道收到数据
# 接收到的数据是一个元组 (接收到的数据,发送方的ip和端口)
# 1024 表示本次接收到的最大字节数
recv_data,addr = udp_socket.recvfrom(1024)
# 关闭套接字
udp_socket.close()
if __name__ == '__main__':
main()
2. TCP总结
1. 创建TCP的socket套接字
2. 连接服务器
3. 发送数据给服务器端
4. 接收服务器端发送来的消息
5. 关闭套接字
import scoket
def main():
# 1. 创建客户端的socket
# socket.AF_INET 表示IPv4协议 AF_INET6表示IPv6协议
# socket.SOCK_STREAM 流式套接字,只要用于TCP协议
client_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 2. 构建目标地址
server_ip = input('请输入服务器端的IP地址:')
server_port = int(input('请输入服务器端的端口号:'))
# 3.连接服务器
# 参数:元组类型 ip是字符串类型 端口号是整型
client_socket.connect((server_ip,server_port))
# 要发送给服务器端的数据
send_data = '我是要发送得服务器端的数据'
# 4. 发送数据
client_socket.send(send_data.encode('gbk'))
# 5. 接受服务器端恢复的消息,没有消息会阻塞
# 1024 表示接收的最大字节数
recv_date = client_socket.recv(1024)
print('接收到的数据是:',recv_date.decode('gbk'))
# 6. 关闭套接字
client_socket.close()
if __name__ == '__main__':
main()
TCP服务器端的创建流程
1. 创建TCP服务端的socket
2. bing 绑定ip地址和端口号
3. listen 使套接字变为被动套接字
4. accept 取出一个客户端连接,用于服务
5. recv/send 接收和发送消息
6. 关闭套接字
import socket
def main():
# 1.创建tcp服务端的socket
server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#2. 绑定
server_socket.bind('',8888)
#3. listen 使套接字变为被动套接字
server_socket.listen(128)
#4. 如果有新的客户端来连接服务器,那么就产生一个新的套接字专门为这个客户端服务
# client_socket 用来为这个客户端服务
# tcp_server_socket 就可以省下来专门等待其他新客户端的链接
client_socket,client_addr = server_socket.accept()
#5. 接受客户端发来的消息
recv_data = client_socket.recv(1024)
print('接受客户端%s的数据:%s'%(str(client_addr),recv_data.decode('gbk')))
#6. 回复数据给客户端
client_socket.send('收到消息'.encode('gbk'))
# 7. 关闭套接字3
client_socket.close()
server_socket.close()
if __name__ == '__main__':
main()
注意点:
- tcp 服务器一般都需要绑定,否则客户端找不到服务器
- tcp 客户端一般不绑定,因为是主动链接服务器,所以只要确定好服务器的ip,port 等信息就好,本地客户端可以随机。
- tcp 服务器中通过listen可以将socket创建出来的主动套接字变为被动的,这是做tcp服务时必须要做的
- 当客户端需要链接服务器时,就需要使用connect进行链接,udp是不需要链接的而是直接发送,但是tcp必须先链接,只有链接成功才能通信。
- 当一个tcp客户端连接服务器时,服务器端会有1个新的套接字,这个套接字用来标记这个客户端,单独为这个客户端服务。
- listen 后的套接字是被动套接字,用来接收新的客户端的连接诶请求的,而accept返回的新套接字是标识这个新客户端的。
- 关闭listen后的套接字意味着被动套接字关闭了,会导致新的客户端不能够链接服务器,但是之前已经链接成功的客户端正常通信。
- 关闭accept返回的套接字意味着这个客户端已经服务完毕
- 当客户端的套接字调用close后,服务器端会recv解阻塞,并且返回的长度为0,因此服务器可以通过返回数据的长度来区别客户端是否已经下线;同理当服务器断开tcp连接的时候客户端同样也会受到0字节数据。
3. 强行关闭客户端和服务器之间的连接?
在socket通信过程中不断检测一个全局变量(开关标记变量),一旦标记变量变为关闭,则调用socket的close方法,循环结束,从而达到关闭连接的目的。
4. 简述TCP 和 UDP 的区别以及优缺点?
UDP是面向无连接的通讯协议,UDP数据包括目的端口号和源端口号信息。
优点:UDP速度快,操作最简单,要求系统资源较少,由于通讯不需要链接,可以实现广播发送。
缺点:UDP传送数据前并不与对方建立连接,对接受到的数据也不发送确认信号,发送端不知道数据是否正确接受,也不重新发送,不可靠。
TCP 是面向链接的通讯协议,通过三次握手建立连接,通讯完成时四次挥手
优点:TCP在数据传递时,有确认,窗口,重传,阻塞等控制机制,能保证数据正确性,较为可靠。
缺点:TCP相对于UDP速度慢一点,要求系统资源较多。
5. 浏览器通过WSGI请求动态资源的过程?
1. 发送HTTP请求动态资源给web服务器
2. web服务器收到请求后通过WSGI调用一个属性给应用程序框架
3. 应用程序框架通过引用WSGI调用web服务器的方法,设置返回的状态和头信息
4. 调用后返回,此时web 服务器保存了刚刚设置的信息
5. 应用程序框架查询数据库,生成动态页面的body的信息
6. 把生成的body信息返回给web服务器
7. web服务器把数据返回给浏览器
6. 浏览器访问www.baidu.com的过程?
先要解析出baidu.com对应的ip地址
- 要先使用arp获取默认网关的mac地址
- 组织数据发送给默认网关(ip还是dns服务器的ip,但是Mac地址是默认网关的Mac地址)
- 默认网关拥有转发数据的能力,把数据转发给路由器
- 路由器根据自己的路由协议,来选择一个合适的较快的路径转发数据给目的网关
- 目的网关(dns服务器所在的网关),把数据转发给dns服务器
- dns服务器查询解析出baidu.com对应的ip地址,并原路返回请求这个域名的client得到了baidu.com对应的ip地址之后,会发送tcp的3次握手,进行连接
- 使用HTTP协议发送请求数据给web服务器
- web服务器收到数据请求之后,通过查询自己的服务器得到相应的结果,原路返回给浏览器。
- 浏览器接受到数据之后通过浏览器自己的渲染功能来显示这个网页。
- 浏览器关闭tcp连接,即4次挥手结束,完成整个访问过程。
7. POST 和GET请求的区别?
GET 请求,请求的数据会附加在URL之后,以?分割URL和传输数据,多个参数用&连接。URL的编码格式采用的是ASCII编码,而不是Unicode,即是说所有的非ASCII字符都要编码之后在传输。
POST请求:POST 请求会把请求的数据放置在HTTP请求包的包体中。上面的item=bandsaw就是实际的传输数据。
因此,GET请求的数据会暴露在地址栏账, 而POST请求则不会。
传输数据的大小:
- 在HTTP规范中,没有对URL的长度和传输的数据大小进行限制。但是在实际开发过程中,对于GET,特定的浏览器和服务器对URL的长度有限制。因此,在使用GET请求时,传输数据会受到URL长度的限制。
- 对于POST,由于不是URL传值,理论上是不会受限制的,但是实际上各个服务器会规定对POST提交数据大小进行限制,Apache,IIS都有各自的配置。
安全性:
- POST的安全性比GET的高。这里的安全是指真正的安全,而不同于上面GET提到的安全方法中的安全,上面提到的安全仅仅是不修改服务器的数据。比如,在进行登录操作,通过GET请求,用户名和密码都会暴露在URL上,因为登录页面有可能被浏览器缓存以及其他人查看浏览器的历史记录的原因,此时的用户名和密码就很容易被他人拿到了。除此之外,GET请求提交的数据还可能造成 Cross-site request frogery 攻击。
效率:GET比POST效率高
POST请求的过称:
- 浏览器请求tcp连接(第一次握手)
- 服务器答应进行tcp连接(第二次握手)
- 浏览器确认,并发送post请求头(第三次握手这个报文比较小,所以HTTP会在此时进行第一次数据发送)
- 服务器返回100 continue相应
- 浏览器开始发送数据
- 服务器返回200 OK响应
GET请求的过程:
- 浏览器请求tcp连接(第一次握手)
- 服务器答应进行tcp连接(第二次握手)
- 浏览器确认,并发送get请求头和数据(第三次握手,这个报文比较小,所以HTTP会在此时进行第一次数据发送)
- 服务器返回200 OK相应。
8. cookie 和session的区别?
1. cookie 数据存放在客户的浏览器上,session数据放在服务器上。
2. cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗考虑到安全应当使用session。
3. session 会在一定时间内保存在服务器上。当访问增多,会比较占用服务器的性能考虑到减轻服务器性能方面,应到使用cookie。
4. 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
5. 建议:将登陆信息等重要信息存放为Session 其他信息如果徐亚保留,可以放在cookie中
9. 三次握手和四次挥手?
三次握手过程:
- 首先客户端向服务端发送一个带有SYN标志,以及随机生成的序号100的报文
- 服务端收到报文后返回一个报文给客户端。
- 客户端再次发送带有ACK标志201序号的报文给服务端
至此三次握手过程结束,客户端开始向服务端发送数据。
补充:SYN:请求询问,ACK:回复,回应。
四次挥手过程:
由于TCP连接是可以双向通信的,因此每个方向都必须单独进行关闭(这句话才是精辟,后面四个挥手的过程都是具体实现的语言描述)
- 客户端发送带有fin标识的报文给服务端,请求通信关闭
- 服务端收到信息后,回复ACK答应关闭客户端通信请求
- 服务端发送带有fin标识的报文给客户端,也请求关闭通信
- 客户端回应ack给服务端,答应关闭服务端的通信请求
10. 什么是tcp的2MSL?
主动发送fin关闭的一方,在4次挥手最后一次要等待一段时间我们称这段时间为2MSL
TIME_WAIT 状态的存在有两个理由:
1. 让4次挥手关闭流程更加可靠
2. 防止丢包后对后续新建的正常连接的传输造成破坏
11. 客户端在TIME-WAIT状态必须等待2MSL的时间?
1. 为了保证客户端发送的最后一个ACK报文段能够达到服务器。这个ACK报文段可能丢失,因而使处在LAST-ACK状态的服务器收不到确认。服务器会超过重传FIN+ACK报文段,客户端就能在2MSL时间收到这个重传的一次确认,重启计时器。最好,客户端和服务器都正常进入到CLOSED状态。如果客户端在TIME-WAIT状态不等待一段时间,而是再发送完ACK报文后立即释放连接,那么就五大收到服务器重传的FIN+ACK报文段,因而也不会在发送一次确认报文。这样,服务器就无法按照正常步骤进入CLOSED状态。
2. 防止已失效的连接请求报文段出现在本连接中。客户端在发送完最后一个ACK确认报文段后,在经过时间2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段。
12. 说说 HTTP和HTTPS区别?
HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是网景公司设计了SSL协议用于对HTTP协议传输的数据进行加密,从而就诞生了HTTPS。简单来说,HTTPS协议是由SSL+HTTP协议构建的可进行加密传输,身份证的网络协议,要比HTTP协议安全。
HTTPS 和 HTTP的区别主要如下:
- https 协议需要ca申请证书,一般免费证书较少,因而需要一定费用。
- http 是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议。
- http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443.
- http 的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输,身份认证的网络协议,比http协议安全。
13. HTTP请求方式都有什么?
根据HTTP标准,HTTP请求可以使用多种请求方式:
HTTP1.0 定义了三种请求方法:GET,POST和HEAD方法。
HTTP1.1 新增了五种请求方法:OPTIONS,PUT,DELETE,TRACE 和 CONNECT 方法。
1. GET 请求指定的页面信息,并返回实体主体。
2. HEAD 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
3. POST 向指定资源提交数据进行处理请求。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
4. PUT 从客户端向服务器传送的数据取代指定的文档的内容。
5. DELETE 请求服务器删除指定的页面。
6. CONNECT HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。
7. OPTIONS 允许客户端查看服务器的性能。
8. TRACE 回显服务器收到的请求,主要用于测试或诊断。
14. 七层模型?IP,TCP/UDP,HTTP,RTSP,FTP 分别在那层?
IP :网路层
TCP/UDP: 传输层
HTTP,RTSP,FTP : 应用层协议
OSI 七层模型 应用层 表示层 会话层 传输层 网络层 数据链路层 物理层
TCP/IP 应用层 传输层 IP层 网络接口层