一、为什么要学习socket
python基础部分已经学完了,而socket是我们基础进阶的课程,也就是说,你自己现在完全可以写一些小程序了,但是前面的学习和练习,我们写的代码都是在自己的电脑上运行的,虽然我们学过了模块引入,文件引入import等等,我可以在程序中获取到另一个文件的内容,对吧,但是那么突然有一天,你的朋友和你说:"把你电脑上的一个文件通过你自己写的程序发送到我的电脑上",这时候怎么办?你是不是会想,what?这怎么搞?就在此时,突然灵感来了,我可以通过qq、云盘、微信等发送给他啊,可是人家说了,让你用自己写的程序啊,嗯,这是个问题,此时又来一个灵感,我给他发送文件肯定是通过网络啊,这就产生了网络,对吧,那我怎么让我的程序能够通过网络来联系到我的朋友呢,并且把文件发送给他呢,那么查了一下,发现网络通信通过socket可以搞,但是怎么搞呢?首先,查询结果是对的,socket就是网络通信的工具,任何一门语言都有socket,他不是任何一个语言的专有名词,而是大家通过自己的程序与其他电脑进行网络通信的时候都用它。知道为什么要学习socket了吧~~朋友们~~而你使用自己的电脑和别人的电脑进行联系并发送消息或者文件等操作就叫做网络通信。
对于一个小白来讲,看到这一节标题的你,此刻的你内心是拒绝的,不明白在说些什么。我理解你的心情,不要惊慌、不要着急,且听我娓娓道来。
大家通过上面的内容大致的了解了一下什么是网络通信,那么在我们的日常生活中,哪里用到了网络通信呢,网络通信的整个流程又是什么样子的呢?我们要学的socket是怎么在网络中发挥作用的呢?让我们怀揣着这三个问题来看下面的讲解。
二、客户端服务端架构(哪里用到了网络通讯)
我们使用qq、微信和别人聊天,通过浏览器来浏览页面、看京东的网站,通过优酷、快播(此处只是怀念一下)看片片啥的等等,通过无线打印机来打印一个word文档等,只要有无线、有网、有4G,我们就能好好的聊天,好好的看片片、好好的购物什么的,对吧,那么这些操作都叫做网络通信,确切来说都需要使用网络通信,前提是你要有网(大家记着这个'网',我下面会给大家详解),原来生活中处处使用了网络通信,我们通过网络通信的不同形式:比如说qq是我们下载到电脑或者手机上的应用程序(qq应用程序就是人家腾讯开发的软件,放到你的电脑或者手机上供你使用的,大概明白应用程序意思就行,不用深究~~),浏览器也是我们下载的应用程序,但是浏览器是通过页面来访问别人的网站的,而打印机我是通过我电脑上的word来操作使用的。根据这些不同的场景或者说不用的沟通方式,在业内划分了下面两个架构(架构:就是不同的组成结构)。在看下面的几个架构之前,我们需要知道什么是客户端,什么是服务端。客户端:安装在你电脑上的qq,浏览器(360浏览器、chrome浏览器、IE浏览器等),当我们使用qq发送消息的时候,消息先发送到了腾讯,然后腾讯在转发到你朋友的qq上,此时你的qq就是客户端,腾讯就是服务端。当我们使用浏览器来看京东的网站的时候,我们电脑上的浏览器就叫做客户端,京东就叫做服务端。
客户端英文名称:Client(使用服务端的服务),服务端英文名称:Server(一直运行着,等待服务别人,不能有一天访问百度,百度页面打不开,不行吧。),下面所说的CS架构就是说的ClientServer架构。
A、硬件CS架构:打印机
B、软件CS架构:QQ、微信、优酷、暴风影音、浏览器(IE、火狐,360浏览器等)。其中浏览器又比较特殊,很多网站是基于浏览器来进行访问的,浏览器和各个网站服务端进行的通讯方式又常被成为BS架构(浏览器英文名称:Browser),web开发就是这个,后面大家知道有前端的课程对吧,前端就是浏览器上的知识,以后你会经常和浏览器打交道,学完前端就可以进行web开发全栈开发了。如果我把所有的东西都做成应用程序是不是很麻烦啊,要装很多的软件对吧,所有就开始有了BS架构,只需要个浏览器就能使用很多的工具了,并且提供了一个统一入口,这也是为什么BS架构火了起来。但是手机端的还是用的应用程序多一些,但是手机端BS架构也是一个趋势,就像微信的小程序和公众号,为什么说是一个趋势呢,不仅仅是因为方便因为省钱,而是提供了一个统一的入口,其实微信早就实现了。统一入口是什么意思呢?就像我们公司经常用的一个公司内部管理系统,请假、打卡、报销、查客户等等,如果这些功能都需要打开一个网页或者app,是不是很难受啊,那么公司就做了这么一个系统,大家在这个系统上关于上班的一些你需要的功能就都能完成了,这就是统一入口。这也是一个开发思想,大程序分成几个小程序,开发速度也快,开发一个小功能就能上线,而不需要等着所有的功能全部开发完成才上线,解耦分治思想,公司做开发时这种思想很流行,迭代开发。说多了。。
不管哪个架构,他们都要进行网络通信,基本都要用socket,我们学习socekt就是为了完成CS架构项目的开发。
三、网络通信的整个流程
还记得上面我说过的那个'网'吗,在这一节就给大家讲解,有些人对网络是既熟悉又陌生,熟悉是因为我们都知道,我们安装一个路由器,拉一个网线,或者用无限路由器,连上网线或者连上wifi就能够上网购物、看片片、吃鸡了,但是这一系列的神操作到底是怎么让我们上网了呢?让我们起底揭秘!由于网络的内容非常的多,本篇博客主要是学socket网络编程,
别忘了端口+IP能够确定一台电脑上的某一个应用程序~~
那么我们通过下面的代码简单看一下socket到底是个什么样子,大概怎么使用:下面的程序就是一个应用程序,和qq啊、微信啊是一样的,都叫做应用程序。
服务端:
服务端.py
1 import socket #导入socket包 2 server = socket.socket() #创建server对象,相当于创建了一部电话 3 ip_port = ("192.168.12.89",8005) #创建IP地址和端口(这个IP是我的电脑ip)相当于创建了一张电话卡 4 server.bind(ip_port) #把server对象和IP和端口绑定,相当于把电话卡查到手机里绑定到一起 5 server.listen() #监听电话 6 print("111111111111") 7 conn,addr = server.accept() #阻塞程序运行,等人来连接我。连接之后会得到一个元组,里面是连线通道Conn和对方的地址(ip+端口) 8 #因为是自己的所以打印输出的话IP会是自身的ip 9 print("2222222222222") 10 from_client_msg = conn.recv(1024) #服务端必须通过两者之间的连接通道来接收消息,所以是conn.recv() 11 print(from_client_msg.decode("utf-8")) #因为只能传输bytes所以客户端的消息需要decode解码 12 conn.close() #关闭通道 13 server.close() #关闭服务端
客户端:
客户端.py
1 client = socket.socket() #创建client对象 2 server_ip_port = ("192.168.12.89",8005) #服务端的IP地址和端口号 3 client.connect(server_ip_port) #client对象连接服务端 4 client.send("123".encode("utf-8")) #因为发送的只能是bytes所以需要用encode转码 5 client.close() #发送完关闭客户端
注意先运行server,然后再运行client。再去看server控制台输出了什么?
这里有两个小练习:
1.server端:接收时间戳时间,转换成格式化时间
client端:每隔10秒钟把时间戳发个server端。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #server端.py中 2 3 import socket 4 import time 5 server = socket.socket() 6 ip_port = ("192.168.12.89",8002) 7 server.bind(ip_port) 8 server.listen() 9 conn,addr = server.accept() 10 while 1: 11 from_client_msg = conn.recv(1024) 12 if from_client_msg.decode("utf-8") != "close": 13 print(from_client_msg.decode("utf-8")) 14 a = from_client_msg.decode("utf-8") 15 t = time.localtime(float(a)) 16 s = time.strftime("%Y-%m-%d %H:%M:%S",t) 17 print(s) 18 else: 19 break 20 conn.close() 21 server.close()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import socket 2 import time 3 count = 0 4 clinet = socket.socket() 5 server_ip_port = ("192.168.12.89",8002) 6 clinet.connect(server_ip_port) 7 while count < 5: #发送五次 8 time.sleep(10) #每隔10秒发送一次 9 clinet.send(str(time.time()).encode("utf-8")) 10 print("向主机发送:",str(time.time()).encode("utf-8")) 11 count += 1 12 clinet.send("close".encode("utf-8")) 13 clinet.close()
2.一直对话的程序
server端收一个发一个
client端发一个收一个
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import socket 2 server = socket.socket() 3 ip_port = ("192.168.12.89",8005) 4 server.bind(ip_port) 5 server.listen() 6 conn,addr = server.accept() 7 while 1: 8 from_client_msg = conn.recv(1024) 9 print("客户端说:",from_client_msg.decode("utf-8")) 10 ser = input("服务器:") 11 conn.send(ser.encode("utf-8")) 12 if ser == "q" or ser == "q".upper(): #输入q跳出while循环关闭服务端 13 break 14 15 server.close() 16 conn.close()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import socket 2 client = socket.socket() 3 server_ip_port = ("192.168.12.89",8005) 4 client.connect(server_ip_port) 5 while 1: 6 cli = input("客户端:") 7 client.send(cli.encode("utf-8")) 8 from_server_msg = client.recv(1024) 9 print("服务器说:",from_server_msg.decode("utf-8")) 10 if from_server_msg.decode("utf-8") == "q"or from_server_msg.decode("utf-8") == "q".upper(): #如果接收到q跳出循环关闭客户端 11 break 12 client.close()