04双系统心得体会,操作系统笔记1

操作系统概论

计算机系统由硬件和软件两部分组成。硬件指计算机的各个部件,包括:存储器、处理器、输入/输出设备及电源、机箱等。软件是指存在计算机系统中或外存储器中的程序及数据的集合。

计算机软件分为系统软件和应用软件。

系统软件是计算机厂商为了便于用户使用计算机而驻存在计算机硬件(如硬盘和软盘)内的系统支持程序。主要的系统软件包括:操作系统、编译和解释程序、汇编程序、连接装入程序、编辑程序和设备驱动程序等。

应用软件是用户为了专门的应用目的,向计算机厂商或其他软件商购买的或者自己开发的解决某一类问题的软件。典型的有:数据库管理软件、图像处理软件、各种办公软件和杀毒软件等。

其中操作系统是一种首要的、最基本的、最重要的系统,也是最庞大、最复杂的系统软件。

安装windows10和ubuntu kylin15.04双系统心得体会

Socket套接字方法

 

1.1 什么是操作系统

通常把操作系统定义为用以控制和管理计算机系统资源,方便用户使用的程序和数据结构的集合。

(1)系统观点——计算机资源管理

在计算机系统中,CPU是计算机硬件的核心,是计算机系统的心脏;操作系统则是计算机软件的核心,是计算机系统的大脑,是整个系统的控制中心,是计算机或智能控制和管理系统中首要的、最重要的、最复杂的系统软件。

计算机系统内运行的程序无时无刻地争夺计算机有限的资源,操作系统的作用在于组织和管理整个计算机系统的硬件和软件资源,在用户和程序之间分配系统资源,使之协调一致、高效地完成各种复杂的任务。

(2)用户观点——用户使用计算机的界面

通过操作系统,计算机能提供更多、质量更高的服务。安装不同的操作系统,呈现在用户面前将会是完全不同的两类“虚拟”计算机,因此操作系统是用户与计算机硬件之间的接口。用户一般通过以下方式获得计算机系统提供的服务。

①命令方式:通过键盘输入有关命令直接使用计算机,以获得计算机所能提供的服务,也可以将若干命令集中在一个文件中,以批处理的方式连续运行命令,获得多种服务。

②系统调用:用户可在应用程序中调用操作系统向用户提供的服务程序,以获得系统服务。

③图形界面:用户可以在窗口环境中通过鼠标、按键、菜单和对话框等方式操纵计算机。

(3)软件观点——程序和数据结构的集合

操作系统是直接与硬件相邻的第一层软件,是由大量极其复杂的系统程序和众多的数据结构集成的。在计算机中的所有软件中,操作系统起到了核心和控制的作用,其它软件的运行都要依赖他的支持。操作系统是在系统中永久运行的超级程序。

一、安装次序

socket 实例类(8-10分钟)

socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)

 family***(*socke*t家族)***

  • socket.AF_UNIX:用于本机进程间通讯,为了保证程序安全,两个独立的程序(进程)间是不能互相访问彼此的内存的,但为了实现进程间的通讯,可以通过创建一个本地的socket来完成
  • socket.AF_INET:(还有AF_INET6被用于ipv6,还有一些其他的地址家族,不过,他们要么是只用于某个平台,要么就是已经被废弃,或者是很少被使用,或者是根本没有实现,所有地址家族中,AF_INET是使用最广泛的一个,python支持很多种地址家族,但是由于我们只关心网络编程,所以大部分时候我么只使用AF_INET)

 socket type***类型***

  • socket.SOCK_STREAM #for tcp
  • socket.SOCK_DGRAM #for udp
  • socket.SOCK_RAW #原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。
  • socket.SOCK_RDM #是一种可靠的UDP形式,即保证交付数据报但不保证顺序。SOCK_RAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,如发送ICMP报文。SOCK_RAM通常仅限于高级用户或管理员运行的程序使用。
  • socket.SOCK_SEQPACKET #废弃了

(Only SOCK_STREAM and SOCK_DGRAM appear to be generally useful.)

 proto=0 请忽略,特殊用途

 fileno=None 请忽略,特殊用途

1.2 操作系统的发展

     很简单,两种安装次序,“先安装windows后安装linux;先安装linux后安装windows”。对于前者,windows安装在C盘,和单系统安装方法一致,之后安装linux,将linux安装到其他分区,这样互不干涉,安装linux的时候可以检测到windows是否安装以及本电脑上是否已经安装了linux,启动的时候可以设置启动的顺序,然后进行启动,笔者就是这样安装的;对于后者,先安装linux,这个时候随便找一个分区进行格式化安装,这没什么问题,而之后安装windows的时候,就没这么好运了,诚然,我们可以把windows按上,可是当我们重新启动的时候就会发现linux竟然不见了,或者说是linux丢失了一些启动识别文件,从而使得bios不能识别,变成了一个废弃的磁盘,由此可以看到linux的安装环境做的比windows智能,或者说windows不屑于进行这样的检查和规避,因此,笔者鼓励使用前者“先安装windows后安装linux”。

服务端套接字函数(2分钟)

  • s.bind() 绑定(主机,端口号)到套接字
  • s.listen() TCP开始监听传入连接。backlog指定在拒绝连接之前,可以挂起的最大连接数量。 backlog等于5,表示内核已经接到了连接请求,但服务器还没有调用accept进行处理的连接个数最大为5, 这个值不能无限大,因为要在内核中维护连接队列
  • s.accept() 被动接受TCP客户的连接,(阻塞式)等待连接的到来 
  服务程序调用accept函数从处于监听状态的流套接字s的客户连接请求队列中取出排在最前的一个客户请求,并且创建一个新的套接字来与客户套接字创建连接通道,如果连接成功,就返回新创建的套接字的描述符,以后与客户套接字交换数据的是新创建的套接字;如果失败就返回 INVALID_SOCKET。该函数的第一个参数指定处于监听状态的流套接字;操作系统利用第二个参数来返回新创建的套接字的地址结构;操作系统利用第三个参数来返回新创建的套接字的地址结构的长度。

 

1.早期的计算机和人工操作方式

在早期的计算机系统中,每一次独立的运行都需要很多的人工干预,操作过程烦琐,占用机时多,也很容易产生错误,在一个程序的运行过程中要独占系统的全部硬件资源,设备利用率很低。

二、安装过程与细节

客户端套接字函数(2分钟)

  • s.connect() 主动初始化TCP服务器连接
  • s.connect_ex() connect()函数的扩展版本,出错时返回出错码,而不是抛出异常

2.脱机输入/输出和批处理系统

(1)脱机输入/输出

为了解决人工干预与CPU速度不匹配的矛盾,提高计算机的使用效率,在计算机中配备了“监控程序”。用户的控制指令和操作步骤可以写在源程序前或专门的控制卡片上。“监控程序”先读入控制命命令,并按命令的指示一步一步自动执行,这就是“操作系统”的雏形。

为了解决慢速输入/输出设备与CPU速度的不匹配问题,可将用户打在卡片上或纸带上的程序和数据通过外围小计算机预先输入到磁带上,运行时再从磁带上高速读入内存,输出也同样通过磁带中转。这种方式就是“脱机输入/输出”。

(2)批处理系统

脱机输入/输出进一步提高了极端及的运行效率,但自前一个惩处运行结束到启动后一个程序运行这段时间内,程序员或操作员还需要进行很多的人工干预。批处理的基本思想是:操作员取来一批作业,将它们输入到磁带中,操作系统先从磁带上将第一个作业读入内存,启动它运行,并将运行结果输出到另一个磁带中,当第一个程序运行完毕,操作系统自动的从输入磁带上读入下一个作业,并予以运行和输出,直到整批作业全部处理完毕。

由于系统作业是成批地进行处理,但内存中智能保持一个运行作业,故该类系统又称为单道批处理系统。

      细节决定成败,安装多个系统,只要有一个地方出现了问题,系统就会崩掉了,甚至导致所有的功夫都会变成无用功。
     2.1、制作启动盘
     在这里,我的电脑是acer(宏碁),4G内存,500G磁盘空间。和普通系统安装方式一样,首先我们需要制作USB引导盘,准备USB3.0或者2.0一个,在网上下载UltraISO软件,不用破解,试用即可,毕竟我们不是经常装系统的,安装完成后打开,这个时候我们就需要镜像和USB设备了。     
     综上所述,我们需要准备的东西有:

公共用途的套接字函数(3-5分钟)

  • s.recv() 接收数据
  • s.send() 发送数据(send在待发送数据量大于己端缓存区剩余空间时,数据丢失,不会发完,可后面通过实例解释)
  • s.sendall() 发送完整的TCP数据(本质就是循环调用send,sendall在待发送数据量大于己端缓存区剩余空间时,数据不丢失,循环调用send直到发完)
  • s.recvfrom() Receive data from the socket. The return value is a pair (bytes, address)
  • s.getpeername() 连接到当前套接字的远端的地址
  • s.close() 关闭套接字
  • socket.setblocking(flag) #True or False,设置socket为非阻塞模式,以后讲io异步时会用
  • socket.getaddrinfo(host, port, family=0, type=0, proto=0, flags=0) 返回远程主机的地址信息,例子 socket.getaddrinfo('luffycity.com',80)
  • socket.getfqdn() 拿到本机的主机名
  • socket.gethostbyname() 通过域名解析ip地址

3.缓冲、终端和DMA技术

(1)缓冲技术

脱机、批处理还没有完全解决CPU与外部设备速度匹配问题,无论你是从读卡机还是从磁带中读入,相对于CPU来说,读入数据的速度总是嫌慢,进一步的解决方法是采用缓冲技术。原理:将数据存放在一个特定的缓冲区,当CPU从缓冲区中得到了数据,在对它进行运算之前吗,再启动输入设备以输入下一个数据至缓冲区。这样CPU在记性运算时,外部设备的输入工作也在同时进行。同样输出也采用缓冲技术。采用带缓冲的输入/输出技术后,CPU与外部设备能做到并行操作,减少了互相等待的时间,极大提高了CPU与各种外部设备的使用效率。

(2)中断技术

具有缓冲的输入输出也带来了新的问题。一个问题时处理机要知道I/O设备什么时候已经完成了输入操作,以便处理数据并启动CIA一个I/O。如果考CPU反复地查询输入设备的状态,就会浪费很多CPU时间。中断技术的出现解决了这个难题 。

只要I/O设备一旦完成输入/输出操作,它就会自动向CPU发出中断信号,CPU收到中断信号后,就会暂停当前的处理工作,在做一些必要的现场保护、中断处理工作后,转图中断服务程序。中断服务程序读出缓冲区的数据,然后启动下一个IU/O操作。从中断服务程序返回后,操作系统恢复被中断的运算过程。

中断处理机构需要在系统栈啥保存中断返回地址,还要保护中断时的其它现场。在完成中断服务,中断程序要恢复原先的中断现场,取得断口地址,使计算机基础原先的处理工作。CPU在处理一个中断事务时,若果又收到一个优先级更高的中断请求,就会暂停当前的中断服务,转为处理更为紧迫的操作,这样就想成了中断的嵌套。

(3)DMA技术

对于慢速的I/O设备,CPU在执行有关并的中断服务程序后,还可利用剩下的大部分时间来执行其他的计算工作。但是对于磁带、磁盘或高速网络通信接口,CPU响应中断和处理数据所费的时间可以比数据到达的时间间隔更长。这样,即使处理机的时间全部用于处理中断和接收输入数据,也仍然会发生数据丢失的情况。

为了解决这个难题,产生了直接存储器存取(DMA)技术。一旦收到DMA发来的中断请求后,CPU在设置了缓冲区、指针和计数器后,DMA就可以不再需要CPU的干预,在内存和设备之间传送整块数据。这样,通过DMA每传送一个数据块仅需要一次中断处理,而不是像低速设备那样每出传送一个数据都需要一次中断处理。

  • USB3.0或者USB2.0一到两个;
  • cn_windows_10_multiple_editions_x64_dvd_6848463.iso;
  • ubuntukylin-15.04-desktop-amd64.iso;
  • UltraISO Portable v9.6.1.3016;

tcp套接字

1.简单套接字
客户端和服务端:两个主要功能,1、建立链接 2、数据通讯
服务端程序会产生两个套接字socket,一个用于三次握手建立链接,另一个用于收发消息数据通讯;
客户端产生一个套接字socket,既可以用于建立链接后,再用于收发消息数据通讯。

client.py

图片 1图片 2

 1 import socket
 2 
 3 #1.买手机
 4 phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 5 print(phone)
 6 
 7 #2.拨号
 8 phone.connect(('127.0.0.1',8081)) 
 9 #端口范围0-65535,0-1024给操作系统用的,若一直无法连接上server,则会一直停留在这一步
10 
11 #3.发收消息
12 phone.send('hello'.encode('utf-8'))
13 data = phone.recv(1024)
14 print(data)
15 
16 #4.关闭
17 phone.close()

View Code

 service.py

图片 3图片 4

 1 import socket
 2 
 3 #1.买手机
 4 phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 5 print(phone)
 6 
 7 #2.绑定手机卡
 8 phone.bind(('127.0.0.1',8081)) #端口范围0-65535,0-1024给操作系统用的
 9 
10 #3.开机
11 phone.listen(5) # 参数表示最大监听数
12 
13 #4.等电话链接
14 print('starting...')
15 conn,client = phone.accept() #返回一个新的套接字conn用于通讯,client为发起通讯链接的客户端的ip和端口号
16 print(conn,client)
17 # print('===>')
18 
19 #5.收,发消息
20 data = conn.recv(1024) # 单位:bytes,  1024代表最大接收1024个bytes
21 print('客户端的数据',data)
22 conn.send(data.upper())
23 
24 #6.挂电话
25 conn.close()
26 
27 #7.关机
28 phone.close()

View Code

4.SPOOLING

使用缓冲技术可以提高CPU与外部设备工作的并行程度,如果CPU处理数据的速度比输入设备快得多,CPU总是要等待输入设备将数据送入缓冲区后才能读取和处理数据,输出也会发生类似的情况。开始时CPU能全速运行,但不久所有的系统缓冲区都会被塞满,此后CPU必须等待输出设备取走缓冲区中的数据,以便可以在其中存放新的输出结果。这种执行速度受到I/O设备限制的作业,成为受限于I/O的作业。另一方面,对于计算量很大的受限于CPU的作业,输入缓冲区经常 是满的,而输出缓冲区经常是空的。因此,缓冲技术虽然是有用的。但是在很多情况下作用并不明显。

磁盘系统的出现极大地改进了脱机输入输出的效果。磁带系统的问题时当CPU从磁带上读入数据时,读卡机等输入设备就不能在磁带的尾部写数据,所以慢速输入设备的数据不能通过磁带机白CPU联机的读入。磁盘设备消除了这个问题。磁盘的读写头很容易从磁盘中的一个区域移动到另一个区域,所以磁盘的读写位置能很快地从读卡机存入磁盘的区域移动到CPU需要读取的下一个记录的区域。

在磁盘系统中,读卡机等设备将数据写到磁盘中,卡片数据的映像记录存放在由操作系统的维护的一张表中。在一个作业执行期间需要请求读卡机输入数据时,实际读入的是存放在磁盘中对应记录向。类似的,当作业要将输出送至打印机是,该输出实际上是通过系统缓冲区写到磁盘中,在该作业运行结束后,才由操作系统自动打印存储在磁盘中的输出结果,这种由操作系统将磁盘模拟为输入/输出设备的处理方式称为SPOOLING(并行的外部设备操作联机)也称为“假脱机”。SPOOLING系统是以磁盘为几乎无限巨大的缓冲区来解决低速的I/O设备与高速CPU之间的速度匹配问题。

相比内存缓冲技术,SPOOLING技术还有其他优点:内存缓冲只能是作业的I/O与本身的计算工作重叠进行,SPOOLING能使多个作业的I/O与计算机重叠地进行。使用SPOOLING技术,计算机在执行一个作业时打印前面已完成了的计算任务的输出结果,还能读入尚未运行的作业,这样使得CPU和多台I/O设备能以很高速度进行并行地工作,提高系统的吞吐量。

SPOOLING还提供一种很重要的结构——缓冲池,操作系统可以根据系统当前的情况在这些作业中挑选下一个运行的作业,以提高CPU和外部设备的利用率。这样操作系统就能是一些CPU受限作业和I/O设备受限作业相搭配运行,以提高系统中各种设备的利用率。

     之后,我们制作启动盘,如果有两个usb设备,我们可以一口气制作两个启动盘,分别用来支持windows和linux的安装,没有的话,我们先制作windows的,等安装完windows之后再制作linux的。方法很简单,打开UltraISO 软件,选中需要制作的镜像,然后在“启动”工具栏中,选择“写入硬盘映像”,然后在对话框中选择USB设备,格式化之后,点击写入即可,如果是windows的话使用NTFS即可,如果是linux的话我们使用FAT32即可。等待一段时间,基本上是十多分钟的样子,引导盘就制作好了。

 2.加上循环套接字

client.py 

图片 5图片 6

 1 import socket
 2 
 3 #1.买手机
 4 phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 5 
 6 print(phone)
 7 
 8 #2.拨号
 9 phone.connect(('127.0.0.1',8080)) #端口范围0-65535,0-1024给操作系统用的
10 
11 while True:
12     msg = input('>>:').strip()
13     if not msg:continue
14     phone.send(msg.encode('utf-8'))  #phone.send(b'')
15     print('has send') #判断能否发空
16     data = phone.recv(1024)
17     print(data.decode('utf-8'))
18 
19 #4.关闭
20 phone.close()

View Code

service.py

图片 7图片 8

 1 import socket
 2 
 3 
 4 phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 5 phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
 6 print(phone)
 7 phone.bind(('127.0.0.1',8080)) #端口范围0-65535,0-1024给操作系统用的
 8 phone.listen(5) #最大链接挂起数
 9 
10 print('starting...')
11 conn,client = phone.accept() #监听
12 # print('===>')
13 
14 #监听到到后,进行通讯循环
15 # while True:
16 #     data = conn.recv(1024) # 单位:bytes,  1024代表最大接收1024个bytes
17 #     #conn tcp协议三次握手的成果,双向链接
18 #     if not data:break #适用与linux操作,当client单方面终止链接时,service端会出现死循环
19 #     print('客户端的数据',data)
20 #     conn.send(data.upper())
21 
22 while True:
23     try:
24         data = conn.recv(1024) # 单位:bytes,  1024代表最大接收1024个bytes
25         #conn tcp协议三次握手的成果,双向链接
26 
27         print('客户端的数据',data)
28         conn.send(data.upper())
29     except ConnectionResetError:
30 
31         break
32 
33 conn.close()
34 phone.close()

View Code

if not data:break 是用于linux的判断,因为在linux中当client端单方面终止时,servce端会一直接收到空,会一直循环print('客户端的数据',data),因此需要加上判断;

except ConnectionResetError: 是针对windows的,当client端单方面终止时,server端会报ConnnectionRsetError。

有时重启服务端时会遇到报错:

图片 9

5.多道程序设计 

脱机操作、缓冲和SPOOLING虽然能使CPU的计算与I/O设备的操作重叠地进行,却有一定的局限性,这些技术都不能使CPU和I/O设备时常保持忙碌状态。当一个作业必须等待I/O操作完成是(如从磁盘读入一个数据),CPU就不能执行下一步运算,往往只能空等。

作业调度使另一种新的计算基数——多道程序设计成为可能,能进一步提法哦CPU的利用率,使它几乎总有任务可执行,也能提高外部设备的利用率,使得多个作业的多种I/O操作可以并行运行。

在多道程序设计系统中,操作系统可以将多个作业存放在作业缓冲池中。在某一时刻,操作系统从缓冲池中挑选一个作业,并开始执行该作业。当执行中的作业因要等待用户键盘输入或等待其它设备I/O操作时,在多道程序设计中,操作胸膛呢过久可在缓冲池中挑选另一个作业,使其运行。当前一个作业结束了的等待状态后就可以再次获得CPU,继续运行下去。只要系统中总是存在可执行的作业,CPU就永远不会闲着。

多道程序设计技术都是相当复杂的,首先为了支持多道程序设计,要有足够大的内存,同时需要有比较复杂的存储和保护机构,同时还需要处理机调度机构,决定哪一个作业占用CPU,除此之外,还需要提供各种外部设备的调度和管理功能。

 图片 10

 

由于重启时系统还没来得及回收端口,因此会提示端口已被占用。

这个是由于你的服务端仍然存在四次挥手的time_wait状态在占用地址(如果不懂,请深入研究1.tcp三次握手,四次挥手 2.syn洪水攻击 3.服务器高并发情况下会有大量的time_wait状态的优化方法)

解决方法:加入一条socket配置,重用ip和端口。

phone.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #就是它,在bind ip和端口 前加。

或者:

实验之前要全部关闭掉所用占用端口的程序,用以下指令
linux:pkill -9 python
windows:taskkill python

 

1.3现代操作系统的类型

       之后我们清理C盘中的文件,将一些重要的文件保存到其他盘或者其他设备中,然后win+R输入cmd打开DOS输入shutdown -s -t 3在三秒之后关闭计算机,这样就可以更深度的关闭计算机,使得装机更稳定。

3.加上 链接循环

之前代码运行可知,client端关闭后,service端也会关闭,但此刻我们想client端关闭后,service端应该能在接收新的client端的链接请求,因此,在建

立链接的部分加入循环。

client.py 

图片 11图片 12

 1 import socket
 2 
 3 #1.买手机
 4 phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 5 
 6 print(phone)
 7 
 8 #2.拨号
 9 phone.connect(('127.0.0.1',8080)) #端口范围0-65535,0-1024给操作系统用的
10 
11 while True:
12     msg = input('>>:').strip()
13     if not msg:continue
14     phone.send(msg.encode('utf-8'))  #phone.send(b'')
15     print('has send') #判断能否发空
16     data = phone.recv(1024)
17     print(data.decode('utf-8'))
18 
19 #4.关闭
20 phone.close()

View Code

service.py

图片 13图片 14

 1 import socket
 2 
 3 phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 4 phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
 5 print(phone)
 6 phone.bind(('127.0.0.1',8080)) #端口范围0-65535,0-1024给操作系统用的
 7 phone.listen(5) #最大链接挂起数
 8 
 9 print('starting...')
10 
11 while True:
12     '''
13     用于监听多次client端的链接,但一次链接发起结束后,
14     可继续监听下一次client端的连接
15     '''
16     conn,client = phone.accept()
17     print(client)
18     while True:
19         try:
20             data = conn.recv(1024) # 单位:bytes,  1024代表最大接收1024个bytes
21             #conn tcp协议三次握手的成果,双向链接
22             if not data: break
23             print('客户端的数据',data)
24             conn.send(data.upper())
25         except ConnectionResetError:
26             break
27     conn.close()

View Code

 1.分时系统

为了降低交互式系统的等待时间和运行时间的比率,系统通过多态终端同时向很多用户提供运行环境,这种分时系统就能以合理的成本向用户提供交互式使用计算机的方便。

现在,大部分系统能同时支持批处理和分时。

分时系统具有以下几个基本特征

①多路性,一台主机可连接多条终端,多个终端用户可以同时使用计算机,共享系统的硬件和软件资源。

②独立性,各用户操作互不干扰,每个用户都认为整个计算机系统被他所独占,为他服务。

③交互性,用户能与系统进行对话,在一个多步骤作业的运行过程中,用户能通过键盘等输入数据或命令,系统获得用户的输入后做出响应,显示执行的状况和结果。

④及时性,系统一般能在1秒钟内接收和响应用户的输入命令或数据,在数秒内显示命令的执行结果。

比较著名的分时系统有:CTTS(兼容分时系统)和MULTICS(多路信息和计算系统)

图片 15

 4.模拟ssh远程执行命令

client.py 

图片 16图片 17

 1 import socket,subprocess
 2 
 3 
 4 phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 5 phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
 6 print(phone)
 7 phone.bind(('127.0.0.1',9900)) #端口范围0-65535,0-1024给操作系统用的
 8 phone.listen(5) #最大链接挂起数
 9 
10 print('starting...')
11 while True:
12     conn,client = phone.accept() #监听
13 
14     while True: #通讯循环
15         try:
16             #1、收命令
17             cmd = conn.recv(1024) # 单位:bytes,  1024代表最大接收1024个bytes
18             #conn tcp协议三次握手的成果,双向链接
19             if not cmd: break
20             #2、执行命令、拿到结果,命令的结果存入stdout=subprocess.PIPE管道,而不是直接输出到终端
21             obj = subprocess.Popen(cmd.decode('utf-8'),shell=True,
22                                    # 指令由client端发送过来是以utf-8解码为bytes发送过来的,因此处应该以utf-8来编码,
23                                    # 因此此处的命令编码应该与client端的一致
24                                    stdout=subprocess.PIPE,
25                                    stderr=subprocess.PIPE)
26             print(obj)
27             stdout = obj.stdout.read()
28             stderr =  obj.stderr.read() #s收发都是bytes格式
29 
30             #3、把命令的结果返回给客户端
31             conn.send(stdout+stderr) #申请一块新的内存空间存放stdout+stderr,会占内存,效率会低
32         except ConnectionResetError:
33             break
34     conn.close()
35 
36 phone.close()

View Code

service.py

图片 18图片 19

 1 import socket
 2 
 3 #1.买手机
 4 phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 5 
 6 print(phone)
 7 
 8 #2.拨号
 9 phone.connect(('127.0.0.1',9900)) #端口范围0-65535,0-1024给操作系统用的
10 
11 while True:
12     msg = input('>>:').strip()
13     if not msg:continue
14     phone.send(msg.encode('utf-8'))
15     # 注意:信息由utf-8解码为bytes格式发送到service端,因此service端也必须把bytes格式以utf-8来编码,
16 
17     data = phone.recv(1024)  #返回值可能超过1024bytes,
18     print(data.decode('gbk'))
19     # windows上,res.stdout.read()读出的就是GBK编码,因此此处也用GBK编码,linux上默认是utf-8
20 
21 #4.关闭
22 phone.close()

View Code

此处注意两个小问题:

  1.service端的命令的编码应该与client端的解码模式对应,client端以utf-8解码指令为bytes,则service端必须以utf-8来编码;

  2.service端的把命令结果发送给client端,client则需要将命令结果进行编码,若serice端在windows上,则以GBK进行编码,若在linux上则以utf-8进行编码。

本文由澳门新葡亰平台官网发布于操作系统,转载请注明出处:04双系统心得体会,操作系统笔记1

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。