PythonNET 网络编程


  • ISO(国际标准化组织)

  • 制定了

  • OSI(Open System Interconnectio),意为开放式系统互联。国际标准化组织(ISO)制定了OSI模型,该模型定义了不同计算机互联的标准,是设计和描述计算机网络通信的基本框架。

    • 网络通信工作流程的标准化

Ps.

  • 高内聚:模块功能尽可能单一,不要掺杂
  • 低耦合:模块之间尽可能减少关联和影响

模型

OSI 七层模型

  • 应用层

    • 提供用户服务,具体功能由特定程序而定
  • 表示称

    • 提供数据压缩、优化、加密
  • 会话层

    • 建立应用级的连接,选择传输服务
  • 传输层

    • 提供不同的传输服务。流量控制
  • 网络层

    • 路由选择,网络互联
  • 链路层

    • 进行数据转换,具体消息的发送,链路连接
  • 物理层

    • 物理硬件、接口设定、网卡路由交换机等
  • 优点:

    1. 将工作流程标准化
    2. 降低了模块之间的耦合度,使每一部分可以单独开发、工作

四层模型

  • 应用层
  • 传输层
  • 网络层
  • 物理链路层

五层模型 TCP/IP模型

  • 应用层(包括应用层、表示层、会话层)
  • 传输层
  • 网络层
  • 链路层
  • 物理层

数据的传输流程

  1. 发送端由应用层物理层逐层添加信息头(首部),最终在物理层发送。
  2. 中间经过节点(交换机,路由器等)转发,发送到接受端
  3. 在接收端根据发送端的每个信息头进行解析,最终消息到应用层展示给用户。
  • 网络协议:在网络通信中双方都遵循的规定。包括建立什么样的网络结构、消息结构、标示代表什么等。

  • 例如:

  • 应用层:TFTP HTTP DNS SMTP

  • 传输层:TCP UDP

  • 网络层:IP

  • 物理层:IEEE

网络相关概念

  • 网络主机:在网络中标示一台计算机 HOST

  • 本地使用:'localhost' '127.0.0.1'

  • 网络使用:'0.0.0.0.' '172.xxx.xxx.xxx'

  • ifconfig/ipconfig:查看IP

  • 获取计算机名

    In [2]: socket.gethostname()

    Out[2]: 'EnweiHaos-MacBook-Pro.local'

      In [3]: socket.gethostbyname('EnweiHaos-MacBook-Pro.local')
    Out[3]: '192.168.2.104''
  • IP地址:网络上确定一台主机网络位置的地址

  • IPv4:点分十进制;192.168.1.2;0~255;32位;有2的32次方种可能

  • IPv6:128位

  • ping ip:测试和某台网络主机是否联通

  • 特殊IP地址

    • 127.0.0.1 本地测试IP
    • 0.0.0.0 使用本机可用IP
    • 192.168.1.0 表示网段IP
    • 192.168.1.1 网关IP
    • 192.168.1.255 广播地址
  • 通过地址获取主机网络信息

    In [7]: socket.gethostbyaddr('www.baidu.com')

    Out[7]: ('127.0.0.1', [], ['119.75.216.20'])

    主机名 别名 网络地址

  • 点分十进制地址转换为二进制

    In [9]: socket.inet_aton('192.168.1.2')

    Out[9]: b'\xc0\xa8\x01\x02'

  • 二进制地址转换为点分十进制

    In [10]: socket.inet_ntoa(b'\xc0\xa8\x01\x02')

    Out[10]: '192.168.1.2'

  • 域名 : 网络服务器地址的名称

    1. 方便记忆
    2. 名称表达一定的含义
  • 网络端口号

    • 端口是网络地址的一部分,用于区分一个网络主机上的网络应用
    • 在一个操作系统中不同的网络应用监听不同的端口号

      • 取值范围:1~65535

        • 1~255:一些众所周知的通用端口
        • 256~1023:系统应用端口
        • 65535:自用端口
        • 建议使用 >10000
      • 获取一个应用的端口信息

        In [11]: socket.getservbyname('mysql')

        Out[11]: 3306

  • 网络字节序: 数据在网络中的传输格式

传输层服务

面向连接的传输服务:基于TCP(Transmission Control Protocol )协议的数据传输

  • 传输特征 :提供可靠的数据传输,可靠性指数据传输过程中无丢失,无失序,无差错,无重复
  • 实现手段:数据传输断开前都需要进行传输和断开的确认
  • 应用情况:适用于传输较大的文件,网络情况良好,需要保证传输可靠性的情况。
  • 比如: 网页的获取,文件下载,邮件传输,登录注册

三次握手:TCP传输在数据传输前建立连接的过程

  1. 客户端向服务器发送连接请求
  2. 服务器收到请求后,回复确认消息,表示允许连接
  3. 客户端收到服务器回复,进行最终标志发送确认连接



四次挥手:TCP传输在连接断开前进行断开确认的过程

  1. 主动发发送报文告知被动方要断开连接
  2. 被动方收到请求后立即返回报文告知已经准备断开
  3. 被动方准备就绪后再次发送报文告知可以断开
  4. 主动方发送消息,确认最终断开

面向无连接的传输服务:基于UDP(User Datagram Protoco)协议的传输

  • 传输特点 : 不保证传输的可靠性,传输过程没有连接和断开的流程,数据收发自由。
  • 使用情况 : 网络情况较差,对传输可靠性要求不高,需要提升传输效率。不便连接,需要灵活收发消息。
  • 比如:网络视频,群聊,广播发送

要求

  1. osi七层模型介绍一下,tcp/ip模型呢?
  2. tcp服务和udp服务有什么区别?
  3. 三次握手和四次挥手是什么意思,过程是怎样的?

socket 套接字编程

  • 目标:根据socket模块提供的接口函数,进行组合使用完成基于TCP或者UDP的网路编程
  • 套接字:完成上述目标的一种编程手段,编程方案

套接字分类:

  • 流式套接字(SOCK_STREAM):传输层基于TCP协议的套接字编程方案。
  • 数据报套接字(SOCK_DGRAM):传输层基UDP协议的套接字编程方案。
  • 底层套接字(SOCK_RAM):访问底层协议的套接字编程。

面向连接的传输--TGP协议--可靠地--流式套接字

面向无连接传输--UDP协议--不可靠--数据报套接字

TCP套接字(流式套接字)服务端编程

import socket

1、创建套接字

    sockfd = socket.socket(socket_family = AF_INET,
socket_type = SOCK_STREAM,
proto = 0)
  • 功能:创建套接字
  • 参数
    • socket_family:选择地址族类型

      • AF_INET -> IPv4
      • AF_INET6 -> IPv6
    • socket_type:套接字类型
      • SOCK_STREAM 流式
      • SOCK_DGRAM 数据报
    • proto:选择子协议类型,通常为0
  • 返回值:返回套接字对象

2、绑定服务端地址

    sockfd.bind(addr)
  • 功能:绑定IP地址

  • 参数:元组(ip,port)

    • localhost 可以被本机用
    • 127.0.0.1 同上
    • 192.168.205.127 可以被所有人用192.168.205.127访问
    • 0.0.0.0 可以被所有人用192.168.205.127访问;也可被自己用127.0.0.1访问

3、设置监听套接字

    sockfd.listen(n)
  • 功能:将套接字设置为监听套接字,创建监听队列
  • 参数:n 表示监听队列大小

    一个监听套接字可以连接多个客户端套接字

4、等待处理客户端连接请求

    connfd, addr = sockfd.accept()
  • 功能:阻塞等待处理客户端连接
  • 返回值
    • connfd 客户端连接套接字
    • addr 连接的客户端地址

      阻塞函数:程序运行过程中遇到阻塞函数则暂停运行,直到某种阻塞条件达成再继续运行

5、消息收发

    data = connfd.recv(buffersize)
  • 功能:接收对应客户端消息

  • 参数:一次最多接收多少字节

  • 返回值:接收到的内容

    如果没有消息则会阻塞

      n = connfd.send(data)
  • 功能:发送消息给对应客户端

  • 参数:要发送的内容,必须是bytes格式

  • 返回值:返回实际发送消息的大小

6、关闭套接字

    sockfd.close()
  • 功能:关闭套接字
# tcp_server.py
from socket import * # 创建套接字
sockfd = socket(AF_INET,SOCK_STREAM) # 绑定地址
sockfd.bind(('0.0.0.0',9900)) # 设置监听
sockfd.listen(5) # 等待接受连接
print("Waiting for connect...")
connfd,addr = sockfd.accept()
print("Connect from",addr) while True:
# 收发消息
data = connfd.recv(1024).decode()
if data == "##":
break
print(data)
n = connfd.send(b'Receive your message')
print("发送了%d字节" % n) # 关闭套接字
connfd.close()
sockfd.close() # telnet macOS下载:https://blog.csdn.net/licheng70356213/article/details/81162660
# $ telnet 127.0.0.1 9996
# Trying 127.0.0.1...
# Connected to localhost.
# Escape character is '^]'.
# hello
# Receive your messageConnection closed by foreign host.

TCP套接字(流式套接字)客户端编程

  • 创建套接字

    必须相同类型的套接字才能通信

  • 建立连接

    sockfd.connect(servr_addr)

    • 功能:建立连接
    • 参数:元组,服务端地址
  • 消息收发

    消息收发要和服务端配合,避免两边都出现recv阻塞

  • 关闭套接字

# tcp_client.py
from socket import * # 创建套接字
sockfd = socket(AF_INET,SOCK_STREAM) # 发起连接
server_addr = ('192.168.207.129',9900)
sockfd.connect(server_addr) while True:
# 消息发送接收
data = input("发送>>")
sockfd.send(data.encode())
if data == '##':
break
data = sockfd.recv(1024)
print("接受到:",data.decode()) # 关闭套接字
sockfd.close()

套接字传输注意事项

  1. 监听套接字存在客户端即可发起连接,但是最终连接的处理需要accept进行处理
  2. 如果连接的另外一段退出,则recv会立即返回空子串不再阻塞。
  3. 当连接的另一端退出时,再试图send发送就会产生BrokenPipeError

网络收发缓冲区

  • 缓冲区作用:

    • 协调收发(处理)速度
    • 减少交互次数

send和recv实际上是和缓冲区进行交互,发送缓冲区满时就无法发送,接收缓冲区满时recv才阻塞

例如:connfd.recv(5)

若超过五个则会重复运行,直到发送完成

TCP粘包(消息粘连,不区分边界)

  • 产生原因:

    • tcp套接字以字节流方式传输,没有消息边界
    • 发送和接收并不能保证每次发送都及时的被接收
  • 影响:

    • 如果每次发送内容表达一个独立的含义此时可能需要处理粘包防止产生歧义
  • 处理方法:

    1. 每次发送的消息添加结尾标志 (人为增加消息边界)
    2. 发送数据结构体
    3. 协调收发速度,每次发送后都预留接收时间

UDP套接字(数据报套接字)服务端编程

1、创建数据报套接字

sockfd = socket(AF_INET,SOCK_DGRAM)

2、绑定地址

sockfd.bind(addr)

3、消息的收发

data,addr = sockfd.recvfrom(buffersize)
  • 功能:接收UDP消息
  • 参数:每次最多接收多大的消息
  • 返回值
    • data接收到的数据
    • addr消息发送端的地址

一次接收一个数据报,如果数据报大小大于buffersize则会丢失部分消息

sockfd.sendto(data,addr)
  • 功能:发送udp消息
  • 参数
    • data发送的消息
    • addr目标地址
  • 返回值:发送的字节数

4、关闭套接字

sockfd.close()
from socket import *

#创建数据报套接字
sockfd = socket(AF_INET,SOCK_DGRAM) #绑定服务端地址
server_addr = ('0.0.0.0',9999)
sockfd.bind(server_addr) #消息收发
while True:
data,addr = sockfd.recvfrom(5)
print("Receive from %s:%s"%\
(addr,data.decode()))
sockfd.sendto('收到你的消息'.encode(),addr) sockfd.close()

UDP套接字(数据报套接字)客户端编程

  1. 创建套接字

    socket(AF_INET,SOCK_DGRAM)
  2. 消息收发

    recvfrom/sendto
  3. 关闭套接字

    close()

sys补充

  1. sys.argv 属性

    • 功能 : 获取命令行参数,得到一个列表
    • 命令本身是 argv[0]
    • 后面的参数从argv[1]开始,默认以空格分隔
    • 使用引号引起来的内容算作一个整体
    • 命令行参数都以字符串放入列表

      例如:
     $ python udp_clinet.py 123 321
    > sys.argv = ['udp_clinet.py','123', '321']```
  2. 直接执行程序

    在程序的第一行加

!/usr/bin/env python3

添加程序的执行权限

chmod 755 file.py

修改后即可通过 ./file.py 运行程序

from socket import *
import sys if len(sys.argv) < 3:
print('''
argv is error!
run as
python3 udp_client.py 127.0.0.1 9999
''')
raise #从命令行输入IP,端口
HOST = sys.argv[1]
PORT = int(sys.argv[2])
ADDR = (HOST,PORT) #创建套接字
sockfd = socket(AF_INET,SOCK_DGRAM) #消息收发
while True:
data = input("消息:")
if not data:
break
sockfd.sendto(data.encode(),ADDR)
data,addr = sockfd.recvfrom(1024)
print("从服务器收到:",data.decode())
sockfd.close()

TCP套接字编程和UDP套接字编程区别

  1. 流式套接字使用字节流的方式传输,数据报套接字以数据报形式传输数据
  2. tcp会有粘包现象,udp有消息边界不会形成粘包
  3. tcp可以保障数据传输完整性,udp则不保证
  4. tcp需要进行listen accept操作,udp不需要
  5. tcp收发消息使用新的套接字,recv send;udp使用recvfrom sendto

补充函数

sendall(data)
  • 功能 : 发送tcp消息
  • 参数 : 要发送的内容,bytes格式
  • 返回值 : 成功返回 None 失败产生异常

套接字对象

  • s.family:获取套接字地址族类型
  • s.type:获取套接字类型
  • s.getsockname():获取套接字的绑定地址
  • s.fileno():获取套接字的文件描述符
    • 文件描述符:每一个IO事件操作系统都会分配一个不同的正整数作为编号,改正整数即为这个IO的文件描述符。

文件描述符是操作系统识别IO的唯一标志

    stdin ---> 0
stdout --> 1
stderr --> 2
  • s.getpeername():获取客户端连接套接字的对应地址

  • s.setsockopt(level,option,value)

    • 功能:设置套接字选项,丰富或者修改套接字属性功能
    • 参数:
      • level 选项类别 SOL_SOCKET
      • option 具体选项
      • value 选项值

  • s.getsockopt(level,option)

    • 功能:获取套接字选项值
    • 参数:
      • level 选项类别 SOL_SOCKET
      • option 具体选项
    • 返回值:选项值

如果要设置套接字选项,最好在创建套接字之后立即设置

from socket import * 

s = socket()

#设置端口立即释放
s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #获取套接字选项值
print(s.getsockopt(SOL_SOCKET,SO_REUSEADDR)) #获取套接字地址族类型
print(s.family) #获取套接字类型
print(s.type) s.bind(('127.0.0.1',9998))
#获取绑定地址
print(s.getsockname()) #获取套接字文件描述符
print(s.fileno()) s.listen(5) while True:
c,addr = s.accept()
print("Connect from",c.getpeername())
c.recv(1024)

PythonNET网络编程1的更多相关文章

  1. PythonNET网络编程4

    本地套接字 Linux 文件 b(块设备文件) c(字符设备文件) d(目录) -(普通文件) l(链接) s(套接字) p(管道) 作用:用于本地不同的程序间进行通信 创建流程 创建本地套接字 so ...

  2. PythonNET网络编程3

    IO IO input output 在内存中存在数据交换的操作都可以认为是IO操作 和终端交互 : input print 和磁盘交互 : read write 和网络交互 : recv send ...

  3. PythonNET网络编程2

    UDP应用:广播 广播:一点发送,多点接收 广播地址:一个网段内有一个指定的广播地址,是该网段的最大地址 192.168.2.255 广播风暴:一个网络中有大量的广播就会产生广播风暴占用大量带宽,影响 ...

  4. 猫哥网络编程系列:HTTP PEM 万能调试法

    注:本文内容较长且细节较多,建议先收藏再阅读,原文将在 Github 上维护与更新. 在 HTTP 接口开发与调试过程中,我们经常遇到以下类似的问题: 为什么本地环境接口可以调用成功,但放到手机上就跑 ...

  5. python select网络编程详细介绍

    刚看了反应堆模式的原理,特意复习了socket编程,本文主要介绍python的基本socket使用和select使用,主要用于了解socket通信过程 一.socket模块 socket - Low- ...

  6. Linux Socket 网络编程

    Linux下的网络编程指的是socket套接字编程,入门比较简单.在学校里学过一些皮毛,平时就是自学玩,没有见识过真正的socket编程大程序,比较遗憾.总感觉每次看的时候都有收获,但是每次看完了之后 ...

  7. 猫哥网络编程系列:详解 BAT 面试题

    从产品上线前的接口开发和调试,到上线后的 bug 定位.性能优化,网络编程知识贯穿着一个互联网产品的整个生命周期.不论你是前后端的开发岗位,还是 SQA.运维等其他技术岗位,掌握网络编程知识均是岗位的 ...

  8. 浅谈C#网络编程(一)

    阅读目录: 基础 Socket编程 多线程并发 阻塞式同步IO 基础 在现今软件开发中,网络编程是非常重要的一部分,本文简要介绍下网络编程的概念和实践. Socket是一种网络编程接口,它是对传输层T ...

  9. C++11网络编程

    Handy是一个简洁优雅的C++11网络库,适用于linux与Mac平台.十行代码即可完成一个完整的网络服务器. 下面是echo服务器的代码: #include <handy/handy.h&g ...

随机推荐

  1. Dynamics CRM2013/2015 插件注冊工具登录后无法显示assembly列表问题的解决的方法

    自微软从2013版本号推出新的插件注冊器后,随着UI的重大更新后,问题也多了非常多.前面已有博客提到注冊assembly时看不到注冊button(http://blog.csdn.net/vic022 ...

  2. js---18miniJquery

    <html> <head> <title>jQuery test</title> </head> <body> <div ...

  3. python-excel操作之xlrd

    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++操作excel文件+++++++++++++++++ ...

  4. 3.索引与string进行映射实现高效查找

    #include <iostream> #include <typeindex>//类型索引 #include <unordered_map>//红黑树 #incl ...

  5. array01.js

    //1.获取指定范围内的随机数 function getRadomNum(min,max){ return Math.floor(Math.random() * (max - min + 1)) + ...

  6. Deep Networks : Overview

    Overview In the previous sections, you constructed a 3-layer neural network comprising an input, hid ...

  7. log大全

    http://www.iconfont.cn/search/index?q=%E6%88%91%E7%9A%84&page=3

  8. yum---rpm软件包管理器

    yum命令是在Fedora和RedHat以及SUSE中基于rpm的软件包管理器,它可以使系统管理人员交互和自动化地更细与管理RPM软件包,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖性 ...

  9. 【习题 8-11 UVA - 1615】Highway

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 每个村庄都有一个范围[li..ri] 只要在这个范围内放点都可以"支配"这个村庄. 则问题就等价于线段上有n个区 ...

  10. 怎样在nat方式的虚拟机下做ssh连接

    很多人在本机做測试都是用桥接的方式让虚拟机上网. 假设ip地址紧张或者根本就不同意我们拥有一个局域网的ip.这时候便能够使用NAT方式+putty来远程操作. 第一步,打开设备-Network-更改网 ...