Python高级知识点学习(七)
HTTP、Socket、TCP概念
socket属于常用的http协议之下的让我们可以使用tcp/ip协议的一个接口。
socket编程
socket编程的模式其实是非常固定的。
上图:
- 左侧server端
- 右侧client端
server必须是随时处于一个监听的状态和服务的状态,因为不知道客户端什么时候会发送来请求。
绑定协议、地址、端口。
每一个应用程序只能占用一个端口,服务器a到服务器b发数据时,数据是不知道是由哪个应用程序接受的,这时候就需要端口机制,每一个应用程序提供一个端口。
socket连接后,只要不关闭连接,服务端可以一直给客户端发送请求,但是在http中,只完成一次发送数据就停止了。
编写测试代码:
新建文件sever.py
import socket server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定ip 端口 server.bind(('0.0.0.0', 8000)) # 监听 server.listen() sock, addr = server.accept() # 接受client端发来的数据 data = sock.recv(1024) # 打印数据 print(data.decode('utf8')) # 给client发数据 sock.send("hello".encode("utf8")) # 关闭 server.close() sock.close()
新建文件client.py
import socket client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(('127.0.0.1', 8000)) # 给server端发数据 client.send("allen".encode("utf-8")) # 接受server端发来的数据 data = client.recv(1024) # 打印数据 print(data.decode('utf8')) # 关闭 client.close()
首先运行server.py,再运行client.py,观察打印结果,可以看到,数据发送接收已经是实现。
socket实现简单聊天
要实现双向交流,肯定不能做close操作,改为一直while循环,
代码:
修改srever.py
import socket server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(("0.0.0.0", 8000)) server.listen() sock, addr = server.accept() while True: # 接受client端发来的数据 data = sock.recv(1024) # 打印数据 print(data.decode('utf8')) re_data = input() # 给client发数据 sock.send(re_data.encode("utf8"))
修改client.py
:
import socket client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(('127.0.0.1', 8000)) while True: # 输入消息 re_data = input() client.send(re_data.encode("utf8")) # 接受client端发来的数据 data = client.recv(1024) # 打印数据 print(data.decode('utf8'))
运行server.py ,再运行client.py,在client.py中输入要发送的文字,在server.py中观察接收到的文字,再在server.py中发送文字,在client.py中查看。
以上就是实现了最初级的基本聊天过程。
如果要在网页上做一个聊天模块,一般都是需要用web socket来实现。
socket多用户聊天
所谓多用户聊天,其实平时我们也经常遇到。
假如你是一位线上客服人员,你需要接待的人员可能同时有多位,当你和A用户聊天时,并不妨碍和B用户C用户给你发消息,而你回消息,回给A用户的消息只有A用户可以看到,B用户是看不到的,接着看如何实现这种功能。
首先client.py的代码不用改动,只需修改server.py:
import socket import threading server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(('0.0.0.0', 8000)) server.listen() def handle_sock(sock, addr): while True: data = sock.recv(1024) print(data.decode("utf8")) re_data = input() sock.send(re_data.encode("utf8")) while True: sock, addr = server.accept() #用线程去处理新接收的连接(用户) client_thread = threading.Thread(target=handle_sock, args=(sock, addr)) client_thread.start()
上边代码把接受处理逻辑放到了线程中,每一个线程存放一个不同的socket,主线程来查看有哪些线程进入。
运行server.py,再运行多个client.py,client.py给server发消息,测试可发现可实现上边的客服功能。
注:真正客服系统要比这个复杂得多,以上代码仅供测试。
socket模拟http请求
我们平常所用到的requests包,是基于 urllib,urllib实际上是基于socket上来完成的。
requests - urlib - socket
如何通过socket去完成类似urllib中http请求呢?
http请求无非就是在tcp协议之上加了一些协议,只要按照这个协议发,就会返回数据。
看代码:
import socket from urllib.parse import urlparse def request_demo(url): # url拆分 url = urlparse(url) host = url.netloc path = url.path if path == "": path = "/" # 建立socket连接 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect((host, 80)) client.send("GET {} HTTP/1.1\r\nHost:{}\r\nConnection:close\r\n\r\n".format(path, host).encode("utf8")) data = b"" # 每次读取1024大小,循环知道读取完毕 while True: d = client.recv(1024) if d: data += d else: break data = data.decode("utf8") print(data) client.close() if __name__ == "__main__": url = 'http://www.baidu.com' request_demo(url) 运行结果包含两部分: 第一部分request header 第二部分html源码
建立连接的过程是比较费时的,一般在使用socket编程都是为了解决长连接的问题,而不是说每发送一个请求数据返回就把它关掉。
很多时候我们需要一个交互的过程,这时候socket就派上用场了,有了socket后我们的代码灵活性高,它完全可以让我们将整个过程变得可以操控。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Java 之 Comparable vs Comparator
Comparable和Compator都是用于给集合排序的接口,但是他们之间的区别是什么呢。 Comparable: 这个接口只有一个方法compareTo。比如我们想通过年龄给用户排序,那么我们的用户要实现Comparable接口的方法,假如一旦要通过用户的评分进行排序,我们就必须要修改compareTo方法。 // o 是要比较的对象 // 返回负数,小于要比较的对象 // 返回 0 ,等于要比较的对象 // 返回正数,大于要比较的对象 public interface Comparable<T> { public int compareTo(T o); } Comparator: 这个接口有两个方法,equals和compare. 要进行比较的类不一定非要实现Comparator接口,由第三方的类实现这个接口来进行排序。 这样的话,排序的种类就可以有很多种,并且像对用户进行排序,我们可以通过年龄,姓名,评分等进行排序也不用修改用户类。我们要做的应该就是写 AgeComparator,NameComparator,RankComparator. public inter...
- 下一篇
杨老师课堂之JavaScript悬浮事件(鼠标移入移出事件)
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kese7952/article/details/83419393 今天给大家分享一个简单的JavaScript事件案例: 该事件属于悬浮事件 改代码逻辑非常简单,主要是 当鼠标移动到按钮上显示一个盒子,移开之后盒子隐藏 JavaScript事件中 onmouseover 代表的是鼠标指针移动到指定的对象上时发生某个动作; onmouseout 代表的是鼠标指针移出该指定的对象上时发生某个动作; xxxx.style 代表一个单独的样式声明 display 是个属性 意为展示或显示的意思 |--- block 以块级元素显示 |--- none 不予以显示,可理解为隐藏 更多具体的属性值可以查看http://www.w3school.com.cn/cssref/pr_class_display.asp 源代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS关闭SELinux安全模块
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- Hadoop3单机部署,实现最简伪集群
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS6,CentOS7官方镜像安装Oracle11G
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS8编译安装MySQL8.0.19
- CentOS6,7,8上安装Nginx,支持https2.0的开启