基于网络编程就是需要客户端和服务端,客户端和服务端都是工作于应用层,要是想要学会所有的协议是很困难的,于是就诞生了socket套接字: Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。 我们无需深入理解tcp/udp协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵循tcp/udp标准的。
.png)
套接字的发展史:套接字分为两种类型1. AF_UNIX;2. AF_INET
基于文件类型的套接字家族
套接字家族的名字:AF_UNIX
unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信
基于网络类型的套接字家族(使用这种类型)
套接字家族的名字:AF_INET
(还有AF_INET6被用于ipv6,还有一些其他的地址家族,不过,他们要么是只用于某个平台,要么就是已经被废弃,或者是很少被使用,或者是根本没有实现,所有地址家族中,AF_INET是使用最广泛的一个,python支持很多种地址家族,但是由于我们只关心网络编程,所以大部分时候我么只使用AF_INET)
套接字的工作流程
先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束
6.基于socket实现简单套接字通信
服务端
import socket
# 类比打电话的流程
# 1.买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# AF_INET是指定的套接字的类型是网络类型,SOCK_STREAM是指定套接字的传输方式是流式传输
# 2.绑定手机卡
phone.bind(('127.0.0.1',8080))
# 端口随便设置,需要注意的是端口是0-65535,但是其中的0-1024是给操作系统使用的
# 3.开机
phone.listen(5)
# listen后的是可挂起的连接数
# 4.等电话链接
# res = phone.accept()
coon, client_addr = phone.accept()
# (<socket.socket fd=240, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 64565)>,
# ('127.0.0.1', 64565))
# res拿到的就是元祖的形式,第一个元素是套接字对象,第二个元素是客户端的IP和端口
# 5.收发消息
data = coon.recv(1024)
print('客户端的数据', data)
# 接收1024个字节,接收数据的最大数,1024是接收字节的最大限制(1.单位是bytes;2.最大接收1024)
coon.send(data.upper())
# 6.挂电话
coon.close()
# 7.关机
phone.close()
客户端
import socket
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# phone.bind(('127.0.1.1',8080))
phone.connect(('127.0.0.1',8080))
# 发、收消息
phone.send('hello'.encode('utf-8'))
data = phone.recv(1024)
print(data)
# 关闭
phone.close()
7.在简单套接字基础上加通信循环
服务端
import socket
# 类比打电话的流程
# 1.买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# AF_INET是指定的套接字的类型是网络类型,SOCK_STREAM是指定套接字的传输方式是流式传输
# 2.绑定手机卡
phone.bind(('127.0.0.1',8080))
# 端口随便设置,需要注意的是端口是0-65535,但是其中的0-1024是给操作系统使用的
# 3.开机
phone.listen(5)
# listen后的是可挂起的连接数
# 4.等电话链接
# res = phone.accept()
# (<socket.socket fd=240, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 64565)>,
# ('127.0.0.1', 64565))
# res拿到的就是元祖的形式,第一个元素是套接字对象,第二个元素是客户端的IP和端口
# 5.收发消息
while True:
coon, client_addr = phone.accept()
data = coon.recv(1024)
print('客户端的数据', data)
# 接收1024个字节,接收数据的最大数,1024是接收字节的最大限制(1.单位是bytes;2.最大接收1024)
coon.send(data.upper())
# 6.挂电话
coon.close()
# 7.关机
phone.close()
客户端
import socket
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# phone.bind(('127.0.1.1',8080))
phone.connect(('127.0.0.1',8080))
# 发、收消息
while True:
msg = input('>>>').strip()
phone.send(msg.encode('utf-8'))
data = phone.recv(1024)
print(data)
# 关闭
phone.close()
socket.send()实际上还是发给了自己的操作系统,操作系统再调用自己的网卡,应用程序来组织数据,操作系统操作TCP协议开始封装数据向下发包,软件的操作方式是应用级别的,操作系统完成应用层以下的4层封装打包
如果强行在client运行时关闭的话,在linux上服务端会一直循环,卡在recv接收处,windows则是直接报错
8.客户端与服务端代码bug修复
服务端可以并发的处理请求(没学到并发的情况下就是不断的循环),可以修改让服务端为客户端一个一个执行
服务端
import socket
# 类比打电话的流程
# 1.买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)#可重复使用IP端口号
# AF_INET是指定的套接字的类型是网络类型,SOCK_STREAM是指定套接字的传输方式是流式传输
# 2.绑定手机卡
phone.bind(('127.0.0.1',8080))
# 端口随便设置,需要注意的是端口是0-65535,但是其中的0-1024是给操作系统使用的
# 3.开机
phone.listen(5)
# listen后的是可挂起的连接数
# 4.等电话链接
# res = phone.accept()
# (<socket.socket fd=240, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 64565)>,
# ('127.0.0.1', 64565))
# res拿到的就是元祖的形式,第一个元素是套接字对象,第二个元素是客户端的IP和端口
# 5.收发消息
coon, client_addr = phone.accept()
while True:
try:
data = coon.recv(1024)
# if not data: break #linux上
print('客户端的数据', data)
# 接收1024个字节,接收数据的最大数,1024是接收字节的最大限制(1.单位是bytes;2.最大接收1024)
coon.send(data.upper())
except ConnectionResetError:
break
# 6.挂电话
coon.close()
# 7.关机
phone.close()
客户端
import socket
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# phone.bind(('127.0.1.1',8080))
phone.connect(('127.0.0.1',8080))
# 发、收消息
while True:
msg = input('>>>').strip()
if not msg:
continue
phone.send(msg.encode('utf-8'))
data = phone.recv(1024)
print(data.decode('utf-8'))
# 关闭
phone.close()
9.实现服务端可以对多个客户端提供服务
服务端
import socket
# 类比打电话的流程
# 1.买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)#可重复使用IP端口号
# AF_INET是指定的套接字的类型是网络类型,SOCK_STREAM是指定套接字的传输方式是流式传输
# 2.绑定手机卡
phone.bind(('127.0.0.1',8080))
# 端口随便设置,需要注意的是端口是0-65535,但是其中的0-1024是给操作系统使用的
# 3.开机
phone.listen(5)
# listen后的是可挂起的连接数
# 4.等电话链接
# res = phone.accept()
# (<socket.socket fd=240, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 64565)>,
# ('127.0.0.1', 64565))
# res拿到的就是元祖的形式,第一个元素是套接字对象,第二个元素是客户端的IP和端口
# 5.收发消息
while True:
coon, client_addr = phone.accept()
print(client_addr)
while True:
try:
data = coon.recv(1024)
# if not data: break #linux上
print('客户端的数据', data)
# 接收1024个字节,接收数据的最大数,1024是接收字节的最大限制(1.单位是bytes;2.最大接收1024)
coon.send(data.upper())
except ConnectionResetError:
break
# 6.挂电话
coon.close()
# 7.关机
phone.close()
客户端
import socket
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# phone.bind(('127.0.1.1',8080))
phone.connect(('127.0.0.1',8080))
# 发、收消息
while True:
msg = input('>>>').strip()
if not msg:
continue
phone.send(msg.encode('utf-8'))
data = phone.recv(1024)
print(data.decode('utf-8'))
# 关闭
phone.close()
10.模拟ssh远程执行命令-项目分析
ssh就是一个基于套接字写的客户端、服务端架构的软件
公司通常都是使用linux,有钱的用unix,没钱的使用centOS这样的服务器,windows的操作系统只是针对用户的体验使用的

11.模拟ssh远程执行命令-代码实现
12.粘包现象
13.粘包底层原理分析
14.解决粘包问题-伪代码实现
15.解决粘包问题-简单版本
16.解决粘包问题-终极版本
17.文件传输功能实现
18.文件传输功能-函数版
19.文件传输功能-面向对象版
20.基于udp协议的套接字介绍
- 路飞学城—Python爬虫实战密训班 第三章
路飞学城—Python爬虫实战密训班 第三章 一.scrapy-redis插件实现简单分布式爬虫 scrapy-redis插件用于将scrapy和redis结合实现简单分布式爬虫: - 定义调度器 - ...
- 路飞学城—Python爬虫实战密训班 第二章
路飞学城—Python爬虫实战密训班 第二章 一.Selenium基础 Selenium是一个第三方模块,可以完全模拟用户在浏览器上操作(相当于在浏览器上点点点). 1.安装 - pip instal ...
- 路飞学城Python爬虫课第一章笔记
前言 原创文章,转载引用务必注明链接.水平有限,如有疏漏,欢迎指正. 之前看阮一峰的博客文章,介绍到路飞学城爬虫课程限免,看了眼内容还不错,就兴冲冲报了名,99块钱满足以下条件会返还并送书送视频. 缴 ...
- 路飞学城-Python开发集训-第3章
学习心得: 通过这一章的作业,使我对正则表达式的使用直接提升了一个level,虽然作业完成的不怎么样,重复代码有点多,但是收获还是非常大的,有点找到写代码的感觉了,遗憾的是,这次作业交过,这次集训就结 ...
- 路飞学城-Python开发集训-第1章
学习体会: 在参加这次集训之前我自己学过一段时间的Python,看过老男孩的免费视频,自我感觉还行,老师写的代码基本上都能看懂,但是实际呢?....今天是集训第一次交作业的时间,突然发现看似简单升级需 ...
- 路飞学城-Python开发集训-第4章
学习心得: 学习笔记: 在python中一个py文件就是一个模块 模块好处: 1.提高可维护性 2.可重用 3.避免函数名和变量名冲突 模块分为三种: 1.内置标准模块(标准库),查看所有自带和第三方 ...
- 路飞学城-Python开发集训-第2章
学习心得: 这章对编码的讲解超级赞,现在对于编码终于有一点认知了,但还没有大彻大悟,还需要更加细心的琢磨一下Alex博客和视频,以前真的是被编码折磨死了,因为编码的问题而浪费的时间很多很多,现在终于感 ...
- 路飞学城-Python开发-第二章
''' 数据结构: menu = { '北京':{ '海淀':{ '五道口':{ 'soho':{}, '网易':{}, 'google':{} }, '中关村':{ '爱奇艺':{}, '汽车之家' ...
- 路飞学城-Python开发-第三章
# 数据结构: # goods = [ # {"name": "电脑", "price": 1999}, # {"name&quo ...
- 路飞学城-Python开发-第一章
# 基础需求: # 让用户输入用户名密码 # 认证成功后显示欢迎信息 # 输错三次后退出程序 username = 'pandaboy' password = ' def Login(username ...
随机推荐
- 推荐一款能支持国密SM2浏览器——密信浏览器
密信浏览器( MeSince Browser )是基于Chromium开源项目开发的国密安全浏览器,支持国密算法和国密SSL证书,同时也支持国际算法及全球信任SSL证书:密信浏览器使用界面清新,干净. ...
- SQL中group by的理解
1.group by A,B,C的分组顺序与汇总: group by A,B,C的分组顺序与order by A,B,C的排序一样.即先按A,如果A一样,则再按B,以此类推. 而数据将在最后指定的分组 ...
- TensorFlow+实战Google深度学习框架学习笔记(12)------Mnist识别和卷积神经网络LeNet
一.卷积神经网络的简述 卷积神经网络将一个图像变窄变长.原本[长和宽较大,高较小]变成[长和宽较小,高增加] 卷积过程需要用到卷积核[二维的滑动窗口][过滤器],每个卷积核由n*m(长*宽)个小格组成 ...
- [SDOI2018]战略游戏(圆方树+虚树)
喜闻乐见的圆方树+虚树 图上不好做,先建出圆方树. 然后答案就是没被选到的且至少有两条边可以走到被选中的点的圆点的数量. 语文不好,但结论画画图即可得出. 然后套路建出虚树. 发现在虚树上DP可以得出 ...
- SSH整合总结(OA项目)
代码规范 环境搭建 Struts2 jar包 struts.xml, web.xml Hibernatejar包:核心包, 必须包, jpa, c3p0, jdbchibernate.cfg.xml, ...
- 编译驱动模块所需的Makefile
目标定义:就是用来定义哪些内容作为模块编译,哪些内容要编译并链接进内核. obj-y += foo.o 表示要由foo.c或者foo.s文件编译得到foo.o并链接进内核: obj-m则表示该文件要作 ...
- $_SERVER 详解
$_SERVER['HTTP_ACCEPT_LANGUAGE']//浏览器语言 $_SERVER['REMOTE_ADDR'] //当前用户 IP . $_SERVER['REMOTE_HOST'] ...
- CF922B Magic Forest
CF922B Magic Forest 题意翻译 题目大意 给定一个正整数nn ,求满足如下条件的三元组(a,b,c)(a,b,c) 的个数: 1 \le a \le b \le c \le n1≤a ...
- 2014年spark开发人员大赛火热进行中!
"发现最有正能量的网络达人".Spark开发人员大赛火热进行! watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3d0dHoxOTc0/ ...
- 打造一个全命令行的Android构建系统
IDE都是给小白程序员的,大牛级别的程序员一定是命令行控,终端控,你看大牛都是使用vim,emacs 就一切搞定” 这话说的虽然有些绝对,但是也不无道理,做开发这行要想效率高,自动化还真是缺少不了命令 ...