python整理-day9

1、TCP/IP

  tcp/ip协议的英文全名:Transmission control protocol and internet protocol

tcp/ip协议是主机接入互联网以及接入互联网的两台主机通信额标准

1、物理层(Physical Layer)
  
  物理层规定了激活、维持、关闭通信端点之间的机械特性、电气特性、功能特性以及过程特性。该层为上层协议提供了一个传输数据的物理媒体。
  
  在这一层,数据的单位称为比特(bit)。
  
  属于物理层定义的典型规范代表包括:EIA/TIA RS-232、EIA/TIA RS-449、V.35、RJ-45等。
  
  2、数据链路层(Data Link Layer)
  
  数据链路层在不可靠的物理介质上提供可靠的传输。该层的作用包括:物理地址寻址、数据的成帧、流量控制、数据的检错、重发等。
  
  在这一层,数据的单位称为帧(frame)。
  
  数据链路层协议的代表包括:SDLC、HDLC、PPP、STP、帧中继等。
  
  3、网络层(Network Layer)
  
  网络层负责对子网间的数据包进行路由选择。此外,网络层还可以实现拥塞控制、网际互连等功能。
  
  在这一层,数据的单位称为数据包(packet)。
  
  网络层协议的代表包括:IP、IPX、RIP、OSPF等。
  
  4、传输层(Transport Layer)
  
  传输层是第一个端到端,即主机到主机的层次。传输层负责将上层数据分段并提供端到端的、可靠的或不可靠的传输。此外,传输层还要处理端到端的差错控制和流量控制问题。
  
  在这一层,数据的单位称为数据段(segment)。
  
  传输层协议的代表包括:TCP、UDP、SPX等。
  
  5、会话层(Session Layer)
  
  会话层管理主机之间的会话进程,即负责建立、管理、终止进程之间的会话。会话层还利用在数据中插入校验点来实现数据的同步。
  
  会话层协议的代表包括:NetBIOS、ZIP(AppleTalk区域信息协议)等。
  
  6、表示层(Presentation Layer)
  
  表示层对上层数据或信息进行变换以保证一个主机应用层信息可以被另一个主机的应用程序理解。表示层的数据转换包括数据的加密、压缩、格式转换等。
  
  表示层协议的代表包括:ASCII、ASN.1、JPEG、MPEG等。
  
  7、应用层(Application Layer)
  
  应用层为操作系统或网络应用程序提供访问网络服务的接口。
  
应用层协议的代表包括:Telnet、FTP、HTTP、SNMP等。

我们看完了osi7层模型,就会想到tcp/ip5层模型,两个是相通的。

这个时候我们就引进socket的概念

Socket是一个软件抽象层,只是负责处理,但是不会去发送数据,发送数据的都是通过协议来进行的

上面这个图就是通过,socket实现的机器交互

socket的一些定义:

  1.基于python3.5.2版本的socket只能收发字节(python2.7可以发送str)

  2.退出只在客户端退出就ok了

  3.s.accept()和s.recv()是阻塞的(基于链接正常)

  4.listen(n) n代表:能挂起的链接数,如果n=1,代表可以链接一个,挂起一个,第三个拒绝

  5.服务端出现端口冲突:修改监听端口号

  6.

    服户端:

      1.send #数据长度

      4.recv #收到确认信息,开始下一步发送

      send

    客户端:

      2.recv #获取数据长度

      3.send #发送确认信息

      recv #循环接收

下面我们就来拿一个程序来进行学习:

Server端程序:

import socket
ip_port=(‘127.0.0.1‘,9999)#必须是元组

s=socket.socket()
s.bind(ip_port)

s.listen(5)
while True:
    conn,addr=s.accept()
    while True:
        try:
            rev_data=conn.recv(1024)
            if len(rev_data)==0:break

            send_data=rev_data.upper()
            print(send_data)

            conn.send(send_data)
        except Exception:
            break

    conn.close()

Client端:

import socket
ip_port=(‘127.0.0.1‘,9999)#必须是元组

s=socket.socket()
s.connect(ip_port)

while True:
    send_data=input(">>:").strip()
    if send_data == "exit":break
    if len(send_data)==0:continue
    s.send(bytes(send_data,encoding=‘utf-8‘))

    recv_data=s.recv(1024)

    print(str(recv_data,encoding=‘utf-8‘))
s.close()

当我先运行了server端的程序,然后在运行server端的程序:

通过程序我们可以知道,功能点就是把client端的输入转化为大写然后返回给client端。

>>:ls
LS
>>:lll
LLL
>>:

这个是客户端的输入和返回结果,我们再看一下server端的结果:

b‘LS‘
b‘LLL‘

这里面可以看出变量类型是byters

在退出的时候,我们需要注意一个地方,就是先暂停client然后再去停止server端,封装就会报端口占用的错误。

如果要避免这个错误,可以使用如下代码:

#1. 加上s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1),
#如下代码
self.host=socket.gethostbyname(socket.gethostname())
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((self.host,self.port))
s.listen(5)

socket编程的时候,发送的是字节,接受到的时候,不需要修改,那会直接把接受到的字节返回回去

recv和accept这两个地方都有堵塞的点(基于连接正常)

再来看一个程序

这个程序主要功能就是传输大数据的方法

Server端:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:wzc
import socket
import subprocess #导入执行命令模块
ip_port=(‘127.0.0.1‘,9999) #定义元祖

s=socket.socket()  #绑定协议,生成套接字
s.bind(ip_port)    #绑定ip+协议+端口:用来唯一标识一个进程,ip_port必须是元组格式
s.listen(5)        #定义最大可以挂起胡链接数

while True:  #用来重复接收新的链接
    conn,addr=s.accept()   #接收客户端的链接请求,返回conn(相当于一个特定胡链接),addr是客户端ip+port
    #收消息
    while True: #用来基于一个链接重复收发消息
            try: #捕捉客户端异常关闭(ctrl+c)
                recv_data=conn.recv(1024) #收消息,阻塞
                if len(recv_data) == 0:break #客户端如果退出,服务端将收到空消息,退出

                #发消息
                p=subprocess.Popen(str(recv_data,encoding=‘utf8‘),shell=True,stdout=subprocess.PIPE) #执行系统命令,windows平
                                                                                                      # 台命令的标准输出是gbk编码,需要转换
                res=p.stdout.read()   #获取标准输出
                if len(res) == 0:   #执行错误命令,标准输出为空,
                    send_data=‘cmd err‘
                else:
                    send_data=str(res,encoding=‘gbk‘)  #命令执行ok,字节gbk---->str---->字节utf-8

                send_data=bytes(send_data,encoding=‘utf8‘)

                #解决粘包问题
                ready_tag=‘Ready|%s‘ %len(send_data)
                conn.send(bytes(ready_tag,encoding=‘utf8‘)) #发送数据长度
                feedback=conn.recv(1024)  #接收确认信息
                feedback=str(feedback,encoding=‘utf8‘)

                if feedback.startswith(‘Start‘):
                    conn.send(send_data)  #发送命令的执行结果
            except Exception:
                break
    #挂电话
    conn.close()

client端:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:Alex Li
import socket
ip_port=(‘127.0.0.1‘,9999)
#买手机
s=socket.socket()
#拨号
s.connect(ip_port)  #链接服务端,如果服务已经存在一个好的连接,那么挂起

while True:        #基于connect建立的连接来循环发送消息
    send_data=input(">>: ").strip()
    if send_data == ‘exit‘:break
    if len(send_data) == 0:continue
    s.send(bytes(send_data,encoding=‘utf8‘))

    #解决粘包问题
    ready_tag=s.recv(1024) #收取带数据长度的字节:Ready|9998
    ready_tag=str(ready_tag,encoding=‘utf8‘)
    if ready_tag.startswith(‘Ready‘):#Ready|9998
        msg_size=int(ready_tag.split(‘|‘)[-1])  #获取待接收数据长度
    start_tag=‘Start‘
    s.send(bytes(start_tag,encoding=‘utf8‘)) #发送确认信息

    #基于已经收到的待接收数据长度,循环接收数据
    recv_size=0
    recv_msg=b‘‘
    while recv_size < msg_size:
        recv_data=s.recv(1024)
        recv_msg+=recv_data
        recv_size+=len(recv_data)
        print(‘MSG SIZE %s RECE SIZE %s‘ %(msg_size,recv_size))

    print(str(recv_msg,encoding=‘utf8‘))
    #挂电话
s.close()

这个程序是要注意的地方是“粘包”

在两侧send的时候,如果两次执行的时间间隔不长的话,就会出现端口占用的断后

使用多进程:

server端

时间: 2024-10-03 13:27:13

python整理-day9的相关文章

Python整理开发环境搭建

Python整理环境搭建,不仅仅包括Python版本的安装,还包括Python命令行,setuptools安装,和工作环境配置等. 1. Python版本的安装 Python的安装 >>> Window下的安装,配置挺简单,稍微注意点的是,PATH配置 >>> Linux 下的安装,大致遵循下面的安装顺序. 网上可以找到很多,Python的安装配置(Windows和Linux下): http://weixiaolu.iteye.com/blog/1617440 安装Mi

Python 整理一

---恢复内容开始--- Python (pailen)最近学习这个语言,其实早在几年前学习perl的时候就知道有这个语言了,在讲perl的那本书后面就推荐学习python,并且还附加了二章的入门.当时初看了一下,发现和perl很相似. 这几天学了python的一些基本东西,整理一下.如下 : #!/usr/bin/python ''' 3.XX版后,默认是UTF-8,支持中文了. ''' #coding=utf-8 '''这是注释,和Perl一样可以使用#号注释单行,但是多行注释是使用3个单引

python小白-day9 数据库操作与Paramiko模块

paramiko模块 SSHClient 用于连接远程服务器并执行基本命令 基于用户名密码连接: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import paramiko # 创建SSH对象 ssh = paramiko.SSHClient() # 允许连接不在know_hosts文件中的主机 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器 ssh.connect(hostna

初学python之day9

一.python学习之堡垒机实例 paramiko模块 1.安装 1)找到python3.5下的Scripts目录 2)打开cmd,切换到Scripts目录下 3)执行 pip3.5.exe install paramiko (如果报错,则执行pip install --upgrade pip 更下pip然后再重新执行步骤3) 执行完3)后安装完成 2.验证是否安装成功 在cmd下进入python模式,输入import paramiko,如果无报错,则执行成功 3.实例 1)SSHClient

python整理-day4

1.Python基础 2.基本数据类型:str,dict,list,int s="wzc" =>str 3.函数式编程 函数定义 内置函数 文件处理 注意: li=[11,22,33,44] def fi(arg): arg.append(55) fi(li) print(li) li=fi(li) print(li) 这里需要说明的是,函数默认返回的是None,所以我们在使用的时候需要通过参数引用 4.其他 三元运算 lambda表达式 s="哈哈" byt

Python开发Day9(多线程多进程)

python线程: 介绍: Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. 使用: Threading方法 .start() : 激活线程 .getName(): 获取线程的名称 .setName() : 设置线程的名称 .name : 获取或设置线程的名称 .is_alive() : 判断线程是否为激活状态 .isAlive() :判断线程是否为激活状态 .setDaemon() 设置为后台线程或前台线程(默认:False);通过一个布尔值设置线程是否为守护线程,必

python学习-day9

一.paramiko模块 paramiko是用Python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接. paramiko主要是通过ssh协议对远程主机进行管理:包括执行远程主机CLI.上传和下载文件等.  二.基于ssh远程连接服务器 1. 基于用户名密码连接 1 import paramiko 2 # 创建SSH对象 3 ssh = paramiko.SSHClient() 4 # 允许连接不在know_hosts文件中的主机 5 ssh.set_miss

python整理-day11

一.线程 1.基本使用 创建线程,两种方式 第一种: import threading def f1(arg): print(arg) t=threading.Thread(target=f1,args=(123,)) t.start() 结果: 123 第二种: import threading class Myclass(threading.Thread): def __init__(self,func,args): self.func=func self.args=args super(M

python之day9(socket)

今日重点socket网络编程: 1,tcp/ip简介: 2,socket简单应用模型: 3,socket单用户模式扩展: 4,socketserver实例: 首先记录一个在day6时没有记录的知识点: 百分比的应用: import sys import time def view_bar(num, total): rate = float(num) / float(total) rate_num = int(rate * 100) r = '\r%d%%' % (rate_num, ) sys.