基于udp协议的套接字通信服务端
from socket import *server=socket(AF_INET,SOCK_DGRAM)    #数据报协议-》udp
server.bind(('127.0.0.1',8080))data,client_addr=server.recvfrom(1)    #recvfrom(1)括号内的数字1表示:b'hello'==>b'h'
print('第一次:    ',client_addr,data)data,client_addr=server.recvfrom(1024)    #recvfrom(1024)括号内的数字1024表示:b'world' =>b'world'
print('第二次:    ',client_addr,data)data,client_addr=server.recvfrom(1024)
print('第三次:    ',client_addr,data)
server.close()客户端
from socket import *client=socket(AF_INET,SOCK_DGRAM)    #数据报协议-》udp
client.sendto('hello'.encode('utf-8'),('127.0.0.1',8080))
client.sendto('world'.encode('utf-8'),('127.0.0.1',8080))
client.sendto(''.encode('utf-8'),('127.0.0.1',8080))
client.close()结果:
第一次: ('127.0.0.1', 54991) b'h'
第二次: ('127.0.0.1', 54991) b'world'
第三次: ('127.0.0.1', 54991) b''

udp并不会产生粘包问题,是由于UDP发送的时候,没有经过Negal算法优化,不会将多个小包合并一次发送出去。另外在UDP协议的接收端,采用了链式结构来记录每一个到达的UDP包,这样接收端应用程序一次recv只能从socket接收缓冲区中读出一个数据包。也就是说,发送端send了几次,接收端必须recv几次(无论recv时指定了多大的缓冲区)

基于tcp协议的套接字通信
服务端
from socket import *server=socket(AF_INET,SOCK_DGRAM)    #数据报协议-》udp
server.bind(('127.0.0.1',8080))while True:data,client_addr=server.recvfrom(1024)print('===>',data,client_addr)server.sendto(data.upper(),client_addr)
server.close()客户端
from socket import *client=socket(AF_INET,SOCK_DGRAM)while True:msg=input('>>:    ').strip()client.sendto(msg.encode('utf-8'),('127.0.0.1',8080))data,server_addr=client.recvfrom(1024)print(data)
client.close()
基于socketserver实现并发的socket(基于tcp协议)
服务端:
import socketserver
class MyHandler(socketserver.BaseRequestHandler):def handle(self):#通信循环while True:try:data=self.request.recv(1024)if len(data)==0:breakself.request.send(data.upper())except ConnectionResetError:break
if __name__=='__main__':s=socketserver.ThreadingTCPServer(('127.0.0.1',8080),MyHandler,bind_and_activate=True) #MyHandler,bind_and_activate默认为trues.server_forever()    #代表连接循环#循环建立连接,每建立一个连接就会启动一个线程(服务员)+调用该对象下的handle方法,专门与刚刚建立好的连接做通信循环客户端
import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080))    #指定服务器Ip和端口while True:msg=input('>>:    ').strip()if len(msg)==0:continuephone.send(msg.encode('utf-8'))data=phone.recv(1024)print(data)
phone.close()
基于socketserver实现并发的socket(基于udp协议)
服务端
import socketserver
class MyHandler(socketserver.BaseRequestHandler):def handle(self):data=self.request[0]print('客户消息',data)self.request[1].sendto(data.upper(),self.client_address)
if __name__=='__main__':s=socketserver.ThreadingUDPServer(('127.0.0.1',8080),MyHandler)s.serve_forever()客户端
import socketclient=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #数据报协议-》udpwhile True:msg=input('>>: ').strip() #msg=''#msg='client444444'client.sendto(msg.encode('utf-8'),('127.0.0.1',8080))data,server_addr=client.recvfrom(1024)print(data)client.close()

计算机系统原理

操作系统发展史
第一代计算机(1940~1955):真空管和穿孔卡片

第一代计算机的产生背景:

第一代之前人类是想用机械取代人力,第一代计算机的产生是计算机由机械时代进入电子时代的标志,从Babbage失败之后一直到第二次世界大战,数字计算机的建造几乎没有什么进展,第二次世界大战刺激了有关计算机研究的爆炸性进展。

lowa州立大学的john Atanasoff教授和他的学生Clifford Berry建造了据认为是第一台可工作的数字计算机。该机器使用300个真空管。大约在同时,Konrad Zuse在柏林用继电器构建了Z3计算机,英格兰布莱切利园的一个小组在1944年构建了Colossus,Howard Aiken在哈佛大学建造了Mark 1,宾夕法尼亚大学的William Mauchley和他的学生J.Presper Eckert建造了ENIAC。这些机器有的是二进制的,有的使用真空管,有的是可编程的,但都非常原始,设置需要花费数秒钟时间才能完成最简单的运算。

在这个时期,同一个小组里的工程师们,设计、建造、编程、操作及维护同一台机器,所有的程序设计是用纯粹的机器语言编写的,甚至更糟糕,需要通过成千上万根电缆接到插件板上连成电路来控制机器的基本功能。没有程序设计语言(汇编也没有),操作系统则是从来都没听说过。使用机器的过程更加原始,详见下‘工作过程’

特点:

没有操作系统的概念
所有的程序设计都是直接操控硬件

工作过程:
程序员在墙上的机时表预约一段时间,然后程序员拿着他的插件版到机房里,将自己的插件板街道计算机里,这几个小时内他独享整个计算机资源,后面的一批人都得等着(两万多个真空管经常会有被烧坏的情况出现)。

后来出现了穿孔卡片,可以将程序写在卡片上,然后读入机而不用插件板

优点:
程序员在申请的时间段内独享整个资源,可以即时地调试自己的程序(有bug可以立刻处理)

缺点:
浪费计算机资源,一个时间段内只有一个人用。
注意:同一时刻只有一个程序在内存中,被cpu调用执行,比方说10个程序的执行,是串行的

第二代计算机(1955~1965):晶体管和批处理系统

第二代计算机的产生背景:

由于当时的计算机非常昂贵,自认很自然的想办法较少机时的浪费。通常采用的方法就是批处理系统。

特点:
设计人员、生产人员、操作人员、程序人员和维护人员直接有了明确的分工,计算机被锁在专用空调房间中,由专业操作人员运行,这便是‘大型机’。

有了操作系统的概念

有了程序设计语言:FORTRAN语言或汇编语言,写到纸上,然后穿孔打成卡片,再讲卡片盒带到输入室,交给操作员,然后喝着咖啡等待输出接口

工作过程:插图


第二代如何解决第一代的问题/缺点:
1.把一堆人的输入攒成一大波输入,
2.然后顺序计算(这是有问题的,但是第二代计算也没有解决)
3.把一堆人的输出攒成一大波输出
优点:批处理,节省了机时

缺点:
1.整个流程需要人参与控制,将磁带搬来搬去(中间俩小人)

2.计算的过程仍然是顺序计算-》串行

3.程序员原来独享一段时间的计算机,现在必须被统一规划到一批作业中,等待结果和重新调试的过程都需要等同批次的其他程序都运作完才可以(这极大的影响了程序的开发效率,无法及时调试程序)

第三代计算机(1965~1980):集成电路芯片和多道程序设计

第三代计算机的产生背景:
20世纪60年代初期,大多数计算机厂商都有两条完全不兼容的生产线。
一条是面向字的:大型的科学计算机,如IBM 7094,见上图,主要用于科学计算和工程计算
另外一条是面向字符的:商用计算机,如IBM 1401,见上图,主要用于银行和保险公司从事磁带归档和打印服务
开发和维护完全不同的产品是昂贵的,同时不同的用户对计算机的用途不同。

IBM公司试图通过引入system/360系列来同时满足科学计算和商业计算,360系列低档机与1401相当,高档机比7094功能强很多,不同的性能卖不同的价格

360是第一个采用了(小规模)芯片(集成电路)的主流机型,与采用晶体管的第二代计算机相比,性价比有了很大的提高。这些计算机的后代仍在大型的计算机中心里使用,此乃现在服务器的前身,这些服务器每秒处理不小于千次的请求。

如何解决第二代计算机的问题1:
卡片被拿到机房后能够很快的将作业从卡片读入磁盘,于是任何时刻当一个作业结束时,操作系统就能将一个作业从磁带读出,装进空出来的内存区域运行,这种技术叫做
同时的外部设备联机操作:SPOOLING,该技术同时用于输出。当采用了这种技术后,就不在需要IBM1401机了,也不必将磁带搬来搬去了(中间俩小人不再需要)

如何解决第二代计算机的问题2:

第三代计算机的操作系统广泛应用了第二代计算机的操作系统没有的关键技术:多道技术

cpu在执行一个任务的过程中,若需要操作硬盘,则发送操作硬盘的指令,指令一旦发出,硬盘上的机械手臂滑动读取数据到内存中,这一段时间,cpu需要等待,时间可能很短,但对于cpu来说已经很长很长,长到可以让cpu做很多其他的任务,如果我们让cpu在这段时间内切换到去做其他的任务,这样cpu不就充分利用了吗。这正是多道技术产生的技术背景

多道技术:

多道技术中的多道指的是多个程序,多道技术的实现是为了解决多个程序竞争或者说共享同一个资源(比如cpu)的有序调度问题,解决方式即多路复用,多路复用分为时间上的复用和空间上的复用。

空间上的复用:将内存分为几部分,每个部分放入一个程序,这样,同一时间内存中就有了多道程序。

时间上的复用:当一个程序在等待I/O时,另一个程序可以使用cpu,如果内存中可以同时存放足够多的作业,则cpu的利用率可以接近100%,类似于我们小学数学所学的统筹方法。(操作系统采用了多道技术后,可以控制进程的切换,或者说进程之间去争抢cpu的执行权限。这种切换不仅会在一个进程遇到io时进行,一个进程占用cpu时间过长也会切换,或者说被操作系统夺走cpu的执行权限)

空间上的复用最大的问题是:程序之间的内存必须分割,这种分割需要在硬件层面实现,由操作系统控制。如果内存彼此不分割,则一个程序可以访问另外一个程序的内存,

首先丧失的是安全性,比如你的qq程序可以访问操作系统的内存,这意味着你的qq可以拿到操作系统的所有权限。

其次丧失的是稳定性,某个程序崩溃时有可能把别的程序的内存也给回收了,比方说把操作系统的内存给回收了,则操作系统崩溃。

第三代计算机的操作系统仍然是批处理
许多程序员怀念第一代独享的计算机,可以即时调试自己的程序。为了满足程序员们很快可以得到响应,出现了分时操作系统

如何解决第二代计算机的问题3:
分时操作系统:
多个联机终端+多道技术

20个客户端同时加载到内存,有17在思考,3个在运行,cpu就采用多道的方式处理内存中的这3个程序,由于客户提交的一般都是简短的指令而且很少有耗时长的,索引计算机能够为许多用户提供快速的交互式服务,所有的用户都以为自己独享了计算机资源

CTTS:麻省理工(MIT)在一台改装过的7094机上开发成功的,CTSS兼容分时系统,第三代计算机广泛采用了必须的保护硬件(程序之间的内存彼此隔离)之后,分时系统才开始流行

MIT,贝尔实验室和通用电气在CTTS成功研制后决定开发能够同时支持上百终端的MULTICS(其设计者着眼于建造满足波士顿地区所有用户计算需求的一台机器),很明显真是要上天啊,最后摔死了。

后来一位参加过MULTICS研制的贝尔实验室计算机科学家Ken Thompson开发了一个简易的,单用户版本的MULTICS,这就是后来的UNIX系统。基于它衍生了很多其他的Unix版本,为了使程序能在任何版本的unix上运行,IEEE提出了一个unix标准,即posix(可移植的操作系统接口Portable Operating System Interface)

后来,在1987年,出现了一个UNIX的小型克隆,即minix,用于教学使用。芬兰学生Linus Torvalds基于它编写了Linux

四代计算机(1980~至今):大规模及超大规模集成电路计算机时代(个人计算机)

1、串行:
    一个任务完完整整地运行完毕后,才能运行下一个任务
2、并发
    看起来多个任务是同时运行的即可,单核也可以实现并发
3、并行:
    真正意义上的多个任务同时运行,只有多核才实现并行
4、cpu的功能:
    cpu是用来做计算,cpu是无法执行I/O操作的,一旦遇到I/O操作,应该让cpu去执行别的任务
5、多道技术
    1、空间上的复用==》多个进程共用一个内存条
    2、时间上的复用==》多个进程复用同一个cpu的时间
        cpu遇到I/O切换:可以提升效率
        一个进程占用cpu时间过长也会切走:为了实现并发效果不得已而为之,反而会降低程序的执行效率

什么是进程:   
    进程指的就是一个正在运行的程序,或者说是程序的运行过程,即进程是一个抽象的概念
    进程是起源于操作系统的,是操作系统最核心的概念,操作系统所有其他的概念都是围绕进程展开的

udp协议没有粘包问题、基于socketserver实现并发的socket(基于tcp、udp协议)、基于udp协议的套接字、操作系统原理以及进程知识相关推荐

  1. 基于UDP协议的socket套接字编程 基于socketserver实现并发的socket编程

    基于UDP协议 的socket套接字编程 1.UDP套接字简单示例 1.1服务端 import socketserver = socket.socket(socket.AF_INET,socket.S ...

  2. TCP协议的粘包问题

    TCP粘包 首先TCP作为面向字节流的传输方式,创建一个tcp的socket,同时在内核中创建一个发送缓冲区和一个接受缓冲区. 当调用write时,向会将数据写入到发送缓冲区中 如果发送的字节数太长, ...

  3. Linux 网络编程详解四(流协议与粘包)

    TCP/IP协议是一种流协议,流协议是字节流,只有开始和结束,包与包之间没有边界,所以容易产生粘包,但是不会丢包. UDP/IP协议是数据报,有边界,不存在粘包,但是可能丢包. 产生粘包问题的原因 1 ...

  4. 为什么tcp不采用停等协议_为什么 TCP 协议有粘包问题

    来自公众号:真没什么逻辑 链接:https://draveness.me/whys-the-design-tcp-message-frame/ 为什么这么设计(Why's THE Design)是一系 ...

  5. http协议解决粘包拆包半包 的编码解码过程、 以及netty 使用http协议的原理

    本文主要介绍netty对http协议解析原理,着重讲解keep-alive,gzip,truncked等机制,详细描述了netty如何实现对http解析的高性能. 1 http协议 1.1 描述 标示 ...

  6. TCP协议的粘包问题(数据无边界性)及解决方法

    其他相关文章:http://c.biancheng.net/view/2350.html https://blog.csdn.net/seamanj/article/details/40063093 ...

  7. tcp协议与粘包现象【转http://www.cnblogs.com/wzd24/archive/2007/12/24/1011932.html】

    Socket开发之通讯协议及处理 在Socket应用开发中,还有一个话题是讨论的比较多的,那就是数据接收后如何处理的问题.这也是一个令刚接触Socket开发的人很头疼的问题. 因为Socket的TCP ...

  8. Netty工作笔记0083---通过自定义协议解决粘包拆包问题1

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 咱们写一个案例,来解决拆包,粘包的问题 自己定义一个协议,先去,这里只有协议内容和长度 然后用以前 ...

  9. Socket TCP协议解决粘包、半包问题的三种解决方案

    什么是粘包.半包问题:         粘包:例如服务端依次将两条消息发送给客户端,我们暂且简单的将这两条消息举例为"Hello"."Unity",而客户端一次 ...

最新文章

  1. 如何写出优质干净的代码,这6个技巧你不能错过!
  2. [二分查找] 二:二分查找的经典例题
  3. 运算符优先级和结合性
  4. rocketmq之控制台rocketmq-console编译安装(二)
  5. Celery 之异步任务、定时任务、周期任务
  6. 《零基础看得懂的C语言入门教程 》——(六)轻轻松松了解C语言的逻辑运算
  7. java字符串最长回文串_Java中的字符串回文程序
  8. arch Linux安装到U盘,如何把ArchLinux安装到U盘上
  9. 终极算法:机器学习和人工智能如何重塑世界
  10. ESET NOD32 v11.0.154
  11. Android手机投屏利器米卓同屏助手
  12. 计算机可移动磁盘无法显示图片,电脑不显示移动硬盘图标?两种解决办法
  13. free, iostat, Linux, top, uptime, vmstat
  14. 人工智能、深度学习和机器学习有哪些区别?
  15. Python数据分析学习系列 十三 Python建模库介绍
  16. 服务器登录信息记录,服务器记录远程桌面登录的信息
  17. 常见波形的傅里叶级数展开式
  18. 【自用】Vue项目中使用自定义字体样式
  19. HTTP Headers 入门
  20. 深富策略:节前大概率休整,节后有望迎来反攻

热门文章

  1. 步步详解IntelliJ IDEA创建springboot项目并运行
  2. Python读取grb2资料
  3. 新一代虚拟驾驶仿真平台
  4. 爬虫之爬取中国移动采购与招标网
  5. VERSA VGG-4422-U-A240多少钱
  6. android USB摄像头做条形码及二维码扫描(1)
  7. Anaconda在Ubuntu下的安装与简单使用
  8. solidworks批量图号分离_SolidWorks图号名称分离宏
  9. 基于 SpringBoot + MyBatis 前后端分离实现的在线办公系统
  10. 科瑞ZTS激光位移传感器使用说明书