博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python高级知识点学习(七)
阅读量:7090 次
发布时间:2019-06-28

本文共 3584 字,大约阅读时间需要 11 分钟。

HTTP、Socket、TCP概念

socket属于常用的http协议之下的让我们可以使用tcp/ip协议的一个接口。

socket编程

img_cc79a915d0758fb5ba7f142170de1167.png
image.png

socket编程的模式其实是非常固定的。

上图:

  • 左侧server端
  • 右侧client端

server必须是随时处于一个监听的状态和服务的状态,因为不知道客户端什么时候会发送来请求。

绑定协议、地址、端口。

每一个应用程序只能占用一个端口,服务器a到服务器b发数据时,数据是不知道是由哪个应用程序接受的,这时候就需要端口机制,每一个应用程序提供一个端口。

socket连接后,只要不关闭连接,服务端可以一直给客户端发送请求,但是在http中,只完成一次发送数据就停止了。

编写测试代码:
新建文件sever.py

import socketserver = 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 socketclient = 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 socketserver = 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 socketclient = 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 socketimport threadingserver = 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 socketfrom urllib.parse import urlparsedef 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后我们的代码灵活性高,它完全可以让我们将整个过程变得可以操控。

转载地址:http://bmiql.baihongyu.com/

你可能感兴趣的文章
参观迅达云成观后感
查看>>
一八年第三天晚上十点半的thinking
查看>>
swift 实践- 11 -- UISlider
查看>>
DirectX11 SDK 下载地址
查看>>
solr4.5分组查询、统计功能介绍
查看>>
Tomcat Server.xml详解
查看>>
CSS媒体查询(@media)
查看>>
如何提取一个转录本的3'UTR区域的序列
查看>>
得到当前日期前一天的零时零分零秒及当前日的零时零分零秒
查看>>
内存堆与栈的区别
查看>>
NHibernate初学者指南(12):日志
查看>>
30 个设计新颖的网站风格展示
查看>>
概念——统一资源定位符(Uniform / Universal Resource Locator,URL)
查看>>
Apache HttpComponents 获取Cookie
查看>>
彻底理解jdbc为什么用反射创建驱动程序对象
查看>>
Oracle内存管理(之五)
查看>>
[nio]dawn的基本概念
查看>>
【数据库摘要】6_Sql_Inner_Join
查看>>
交叉熵代价函数(损失函数)及其求导推导
查看>>
Android UI开源框架
查看>>