网络编程之socket
一 学习socket
socket是我们基础进阶的课程,我们写的代码都是在自己的电脑上运行的,虽然我们学过了模块引入,文件引入import等等,我可以在程序中获取到另一个文件的内容,对吧,但是那么突然有一天,你的朋友和你说:"把你电脑上的一个文件通过你自己写的程序发送到我的电脑上",这时候怎么办?你是不是会想,what?这怎么搞?就在此时,突然灵感来了,我可以通过qq、云盘、微信等发送给他啊,可是人家说了,让你用自己写的程序啊,嗯,这是个问题,此时又来一个灵感,我给他发送文件肯定是通过网络啊,这就产生了网络,对吧,那我怎么让我的程序能够通过网络来联系到我的朋友呢,并且把文件发送给他呢,那么查了一下,发现网络通信通过socket可以搞,但是怎么搞呢?首先,查询结果是对的,socket就是网络通信的工具,任何一门语言都有socket,他不是任何一个语言的专有名词,而是大家通过自己的程序与其他电脑进行网络通信的时候都用它。知道为什么要学习socket了吧~~朋友们~~而你使用自己的电脑和别人的电脑进行联系并发送消息或者文件等操作就叫做网络通信。
二 客户端\服务端架构(哪里用到了网络通信)
客户端英文名称:Client(使用服务端的服务),服务端英文名称:Server(一直运行着,等待服务别人,不能有一天访问百度,百度页面打不开,不行吧。),下面所说的C\S架构就是说的Client\Server架构。
a.硬件C\S架构:打印机。
b.软件C\S架构:QQ、微信、优酷、暴风影音、浏览器(IE、火狐,360浏览器等)。其中浏览器又比较特殊,很多网站是基于浏览器来进行访问的,浏览器和各个网站服务端进行的通讯方式又常被成为B\S架构(浏览器英文名称:Browser),web开发就是这个,后面大家知道有前端的课程对吧,前端就是浏览器上的知识,以后你会经常和浏览器打交道,学完前端就可以进行web开发全栈开发了。如果我把所有的东西都做成应用程序是不是很麻烦啊,要装很多的软件对吧,所有就开始有了B\S架构,只需要个浏览器就能使用很多的工具了,并且提供了一个统一入口,这也是为什么B\S架构火了起来。但是手机端的还是用的应用程序多一些,但是手机端B\S架构也是一个趋势,就像微信的小程序和公众号,为什么说是一个趋势呢,不仅仅是因为方便因为省钱,而是提供了一个统一的入口,其实微信早就实现了。统一入口是什么意思呢?就像我们公司经常用的一个公司内部管理系统,请假、打卡、报销、查客户等等,如果这些功能都需要打开一个网页或者app,是不是很难受啊,那么公司就做了这么一个系统,大家在这个系统上关于上班的一些你需要的功能就都能完成了,这就是统一入口。这也是一个开发思想,大程序分成几个小程序,开发速度也快,开发一个小功能就能上线,而不需要等着所有的功能全部开发完成才上线,解耦分治思想,公司做开发时这种思想很流行,迭代开发。说多了。。
不管哪个架构,他们都要进行网络通信,基本都要用socket,我们学习socekt就是为了完成C\S架构项目的开发
三 网络通信的整个流程
还记得上面我说过的那个'网'吗,在这一节就给大家讲解,有些同学对网络是既熟悉又陌生,熟悉是因为我们都知道,我们安装一个路由器,拉一个网线,或者用无限路由器,连上网线或者连上wifi就能够上网购物、看片片、吃鸡了,但是这一系列的神操作到底是怎么让我们上网了呢?让我们起底揭秘!由于网络的内容非常的多,本篇博客主要是学socket网络编程,所以我把网络这方面的内容放到了我另外一篇博客上,这个博客很简单,不是什么深入研究类的博客,没有学过网络的或者说对网络不太熟悉的同学可以去看看,地址是网络通信的整个流程,(这里跳转的是我的老师,吴超老师的博客)有网络基础的同学,可以直接往下面学习,如果你自认上学时是个学渣,也可以过去大致溜一眼~~~将来你面向的是开发,所有网络这一块对你来讲就是大致知道就可以了,但是以后想在技术上有深造,那么就需要你深入的研究一下网络了,内容非常多,学海无涯~~
别忘了端口+IP能够确定一台电脑上的某一个应用程序~~
那么我们通过下面的代码简单看一下socket到底是个什么样子,大概怎么使用:下面的程序就是一个应用程序,和qq啊、微信啊是一样的,都叫做应用程序。
import socket #创建一个socket对象 server = socket.socket() #相当于创建了一部电话 ip_port = ('192.168.111.1',8001) #创建一个电话卡 server.bind(ip_port) #插上电话卡 server.listen(5) #监听着电话,我能监听5个,接到一个电话之后,后面还能有四个人给我打电话,但是后面这四个人都要排队等着,等着我第一个电话挂掉,再来第6个的时候,第六个人的手机会报错 print('11111') #等着别人给我打电话,打来电话的时候,我就拿到了和对方的这个连线通道conn和对方的电话号码addr conn,addr = server.accept() #阻塞住,一直等到有人连接我,连接之后得到一个元祖,里面是连线通道conn和对方的地址(ip+端口) print('22222') print(conn) print('>>>>>>>>>',addr) while True: from_client_data = conn.recv(1024) #服务端必须通过两者之间的连接通道来收消息 from_client_data = from_client_data.decode('utf-8') print(from_client_data) if from_client_data == 'bye': break server_input = input('明威说>>>>:') conn.send(server_input.encode('utf-8')) if server_input == 'bye': break conn.close() #挂电话 server.close() #关手机 test_server.py
listen(3),这个3的意思是我连接着一个,后面还可以有三个排队的,也就是支持4个人的服务,但是后面三个要排队。
#_*_coding:utf-8_*_ import socket import time client = socket.socket() server_ip_port = ('192.168.111.1',8001) client.connect(server_ip_port) while True: client_input = input('小文说>>>>:') client.send(client_input.encode('utf-8')) #给服务端发送消息 if client_input == 'bye': break from_server_data = client.recv(1024) print('来自服务端的消息:',from_server_data.decode('utf-8')) if from_server_data.decode('utf-8') == 'bye': break client.close() #客户端挂电话 test_client.py
注意:先运行server,然后再运行client,然后你会发现client这个文件再输出台的地方让你输入内容,你输入一个内容然后回车,你会发现server那边的控制台就输出了以client发送的内容
小练习:
import time t = time.time() #获取时间戳 str_t = str(t) print(str_t) stru_t = time.localtime(float(str_t)) #将时间戳转换为结构化时间 s2 = time.strftime('%Y-%m-%d %H:%M:%S',stru_t) #将结构化时间转为格式化时间 print(s2,type(s2)) 时间转换(先自己写,先不要看这里面的内容)
例子:
服务端
#导入socket模块 import socket #创建socket对象,创建了一个手机 server = socket.socket() #给程序设置一个ip地址和端口号,买了个手机卡 ip_port = ('192.168.12.11',8002) #绑定ip地址和端口,插卡 server.bind(ip_port) #监听ip地址和端口,简称开机 server.listen() #等待建立连接, conn是连接通道,addr是客户端的地址 conn,addr = server.accept() #服务端通过conn连接通道来收发消息,通过recv方法,recv里面的参数是字节(B),1024的意思1024B=1KB from_client_msg = conn.recv(1024) print('高说:',from_client_msg.decode('utf-8')) #回复消息:通过send方法,参数必须是字节类型的, conn.send('约吗'.encode('utf-8')) #关闭通道,关电话,通过close方法 conn.close() #关闭socket对象,关机 server.close()
客户端
#导入socket import socket #创建一个socket对象 client = socket.socket() #找到服务端的ip地址和端口 server_ip_port = ('192.168.12.11',8002) #连接服务端的应用程序,通过connect方法,参数是服务端的ip地址和端口,打电话 client.connect(server_ip_port) #发消息,用的send方法,但是调用者是client的socket对象 client.send('约吗?'.encode('utf-8')) from_server_msg = client.recv(1024) print('高的女朋友说:',from_server_msg.decode('utf-8')) client.close()
服务端
#导入socket模块 import socket #创建socket对象,创建了一个手机 server = socket.socket() #给程序设置一个ip地址和端口号,买了个手机卡 ip_port = ('192.168.12.11',8002) #绑定ip地址和端口,插卡 server.bind(ip_port) #监听ip地址和端口,简称开机 server.listen() print('111111') #等待建立连接, conn是连接通道,addr是客户端的地址,阻塞程序 conn,addr = server.accept() print('222222') #服务端通过conn连接通道来收发消息,通过recv方法,recv里面的参数是字节(B),1024的意思1024B=1KB from_client_msg = conn.recv(1024) print('高旺说:',from_client_msg.decode('utf-8')) to_client_msg = input('高旺的女朋友说:') #回复消息:通过send方法,参数必须是字节类型的, conn.send(to_client_msg.encode('utf-8')) #关闭通道,关电话,通过close方法 conn.close() #关闭socket对象,关机 server.close()
客户端
#导入socket import socket #创建一个socket对象 client = socket.socket() #找到服务端的ip地址和端口 server_ip_port = ('192.168.12.11',8002) #连接服务端的应用程序,通过connect方法,参数是服务端的ip地址和端口,打电话 client.connect(server_ip_port) to_server_msg = input('高旺说:') #发消息,用的send方法,但是调用者是client的socket对象 client.send(to_server_msg.encode('utf-8')) from_server_msg = client.recv(1024) print('高旺的女朋友说:',from_server_msg.decode('utf-8')) client.close()