Socket编程的意义是什么,Socket编程学习涉及哪些知识
Admin 2022-06-28 群英技术资讯 507 次浏览
TCP协议,面向连接,可靠,基于字节流的传输层通信协议;UDP协议无连接,不可靠,基于数据包的传输层协议。
TCP协议在建立连接的过程需要经历三次握手,断开连接则需要经历四次挥手,而这建立连接的过程增加了传输过程中的安全性。
而建立连接的过程则会消耗系统的资源,消耗更多的时间,而相比较UDP协议传输过程则不会出现这种问题。
总结来讲,基于TCP协议传输,需要不断的确认对方是否收到信息,从而建立连接(确认过程次数有限制,即三次握手),UDP协议传输则
不需要确认接收端是否收到信息,只需要将信息发给对方。
TCP/IP协议栈就是一系列网络协议,可以分为四层模型来分析:应用层、传输层、网络层、链路层;
HTTP协议(超文本传输协议)就是在这一协议栈中的应用层协议;HTTP协议简单来说,它的作用就是规范数据的格式,让程序能够方便的识别,并且收发双方都需要遵循同样的协议格式进行数据传输。(应用层的协议也和HTTP协议的作用类似,不一样的是定义不同的数据格式。)
Socket可以理解为TCP/IP协议栈提供的对外的操作接口,即应用层通过网络协议进行通信的接口。Socket可以使用不同的网络协议进行端对端的通信;
Server端:
建立连接(socket()函数创建socket描述符、bind()函数绑定特定的监听地址(ip+port)、listen()函数监听socket、accept()阻塞等待客户端连接)
数据交互(read()函数阻塞等待客户端发送数据、write()函数发送给客户端数据)
Client端:
建立连接(socket()函数创建socket描述符、connect()函数向指定的监听地址发送连接请求)
数据交互(wirte()函数发送服务端数据、read()函数足阻塞等待接受服务端发送的数据)
webosocket是一种通信协议,不同于HTTP请求,客户端请求服务端资源,服务端响应的通信过程;websocket允许服务端主动
向客户端推送消息,同时做到客户端和服务端双向通讯的协议。(具体底层原理有待后面实践,暂时未接触)
HTTP协议(超文本传输协议),属于TCP/IP协议栈中应用层的协议。用于规范传输数据的格式,是一种客户端和服务端传输的规则。
WSGI协议则是Python定义的Web服务器和框架程序通信的接口规则。两者联系不大,强行说的话,Python框架程序主要处理的是HTTP请求。
(后期可以实现一个WSGI协议的Python框架,用于处理HTTP请求的实验。)
主流Web框架:Django、Flask
异步Web框架:Tornado(内置异步模块)、Snaic(Python自带asyncio)、FastAPI(基于Starlette库) 、aiohttp(基于asyncio)
asyncio是一个异步IO库,aiohttp就是基于asyncio的异步HTTP框架(支持客户端/服务端)
Python提供了基本的socket模块:
socket模块:
# -*- coding: utf-8 -*- from socket import socket, AF_INET, SOCK_STREAM def echo_handler(sock ,address): print("Get Connection from address:", address) while True: response = sock.recv(8192) if not response: break print(f"Got {response}") sock.sendall(response) def echo_server(address, back_log=5): sock = socket(AF_INET, SOCK_STREAM) sock.bind(address) sock.listen(back_log) while True: sock_client, address = sock.accept() echo_handler(sock_client, address) if __name__ == "__main__": echo_server(('localhost', 5000))
代码详解:
存在的问题:当出现多个客户端请求时,由于是单个线程会发生阻塞的情况,所以如果需要多线程处理多个客户端请求,可以这样改;
from threading import Thread while True: client_sock, address = sock.accept() thread = Thread(target=echo_handler, args=(client_sock, address)) thread.start()
这样的话,就会在每个客户端请求的时候,生成一个子线程然后处理请求;
(但是存在一个问题:当突然大量请求连接,消耗系统资源达到上限后,很可能造成程序无法处理后续请求。)
socketserver模块:
from socketserver import BaseRequestHandler, TCPServer class EchoHandler(BaseRequestHandler): def handle(self): print("Got Connection From: %s" % str(self.client_address)) while True: msg = self.request.recv(8192) if not msg: break self.request.send(msg) if __name__ == "__main__": server = TCPServer(("", 5000), EchoHandler) server.serve_forever()
from socketserver import StreamRequestHandler, TCPServer, ThreadingTCPServer import time class EchoHandler(StreamRequestHandler): def handle(self): print("Got Connection Address: %s" % str(self.client_address)) for line in self.rfile: print(line) self.wfile.write(bytes("hello {}".format(line.decode('utf-8')).encode('utf-8'))) if __name__ == "__main__": serv = ThreadingTCPServer(("", 5000), EchoHandler) serv.serve_forever()
代码详解:
socket模块:
# -*- coding: utf-8 -*- from socket import socket, AF_INET, SOCK_STREAM import time def request_handler(): start_time = time.time() sock_client = socket(AF_INET, SOCK_STREAM) sock_client.connect(('localhost', 5000)) book_content = "" with open("send_books.txt", "r") as f: book_content = f.read() content_list = book_content.split("\n") for content in content_list: if content: sock_client.send((content).encode()) time.sleep(2) response = sock_client.recv(8192) print(response) end_time = time.time() print("总共耗时:", end_time-start_time) if __name__ == "__main__": request_handler()
Socket模块:
from socket import socket, AF_INET, SOCK_DGRAM import time def time_server(address): sock = socket(AF_INET, SOCK_DGRAM) sock.bind(address) while True: msg, addr = sock.recvfrom(8192) print('Get message from', addr) resp = time.ctime() sock.sendto(resp.encode('ascii'), addr) if __name__ == "__main__": time_server(('', 5000))
代码不详解,和之前的差不多,注意不同的协议就完事了
客户端测试:
from socket import socket, AF_INET, SOCK_DGRAM if __name__ == "__main__": s = socket(AF_INET, SOCK_DGRAM) s.sendto(b'hello', ('localhost', 5000)) text = s.recvfrom(8192) print(text)
socketserver模块:
from socketserver import BaseRequestHandler, UDPServer import time class TimeHandler(BaseRequestHandler): def handle(self): print("Got Connection %s".format(str(self.client_address))) data = self.request[0] print(data) msg, sock = self.request print(msg) data = time.ctime() sock.sendto(data.encode('ascii'), self.client_address) if __name__ == "__main__": u = UDPServer(("localhost", 9999), TimeHandler) u.serve_forever()
代码不在赘述,如果需要多线程处理并发操作可以使用ThreadingUDPServer
关于本篇介绍Python Socket编程,大都是皮毛,只是谈到了Python实际处理socket的几个模块,
关于socket底层方面的知识并未提及,先了解个大概,从实际使用方面出发,在实际使用过程中结合
计算机网络知识,能够对socket在整个TCP/IP协议栈中的作用。
socket和socketserver模块都可以用来编写网络程序,不同的是socketserver省事很多,你可以专注
业务逻辑,不用去理会socket的各种细节,包括不限于多线程/多进程,接收数据,发送数据,通信过程。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
Python可视化技术中,经常会运用到3D曲面图,今天我们就来讲一下如何实现3D曲面图。Axes3D类的对象使用plot_surface()方法绘制3D曲面图,该方法的语法格式如下所示:
在列表,元组,实例,类,字典和函数中存在循环引用问题。有 __del__ 方法的实例会以健全的方式被处理。给新类型添加GC支持是很容易的。
这篇文章主要为大家介绍了Python提升运行速度的几个小技巧,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
这篇文章主要介绍pytorch实现多gpu训练的内容,对新手学习和了解pytorch具有一定参考价值,感兴趣的朋友就继续往下看吧,希望大家阅读完这篇文章能有所收获,接下来小编带着大家一起了解看看。
Python内置函数-hash() 函数。hash() 用于获取取一个对象(字符串或者数值等)的哈希值。
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008