week 7

python - 网络

网络基础

  • 什么是网络通讯:

使用网络能够把多方链接在一起,然后可以进行数据传递

所谓的网络编程就是,让在不同的电脑上的软件能够进行数据传递,即进程之间的通信

  • 网络通讯基本概念:

1、IP地址

用来在网络中标记一台电脑,比如192.168.1.1;在本地局域网上是唯一的。

2、IP地址有五类:

A:1.0.0.1-126.255.255.254 网络地址的最高位必须是“0”,可用的A类网络有126个,每个网络能容纳1677214个主机

B:128.1.0.1-191.255.255.254 网络地址的最高位必须是“10”,可用的B类网络有16384个,每个网络能容纳65534主机

C:192.0.1.1-223.255.255.254 网络地址的最高位必须是“110”C类网络可达2097152个,每个网络能容纳254个主机

D:224.0.0.1-239.255.255.254 D类IP地址第一个字节以“1110”开始,它是一个专门保留的地址。它并不指向特定的网络,目前这一类地址被用在多点广播(Multicast)中多点广播地址用来一次寻址一组计算机 s 地址范围

E:以“1111”开始,为将来使用保留,E类地址保留,仅作实验和开发用

子网掩码:区分网络号和主机号

3、私有ip:

国际规定有一部分IP地址是用于我们的局域网使用,也就是属于私网IP,不在公网中使用的,(本地局域网上的IP,专门为组织机构内部使用)它们的范围是:

10.0.0.0~10.255.255.255

172.16.0.0~172.31.255.255

192.168.0.0~192.168.255.255

IP地址127.0.0.1~127.255.255.255用于回路测试,

如:127.0.0.1可以代表本机IP地址,用http://127.0.0.1就可以测试本机中配置的Web服务器。

4、ifconfig:

显示所有网卡的信息:(windows中使用ipconfig)

5、ping:

通常用ping来检测网络是否正常

  • 端口:(用来标记区分进程)

1、一台拥有IP地址的主机可以提供许多服务,比如HTTP(万维网服务)、FTP(文件传输)、SMTP(电子邮件)等,这些服务完全可以通过1个

IP地址来实现。那么,主机是怎样区分不同的网络服务呢?显然不能只靠IP地址,因为IP地址与网络服务的关系是一对多的关系。实际上是通过“IP地

址+端口号”来区分不同的服务的。 需要注意的是,端口并不是一一对应的。比如你的电脑作为客户机访问一台WWW服务器时,WWW服务器使用“80”端口

与你的电脑通信,但你的电脑则可能使用“3457”这样的端口。

2、端口是通过端口号来标记的,端口号只有整数,范围是从0到65535

3、端口号不是随意使用的,而是按照一定的规定进行分配。知名端口是众所周知的端口号,范围从0到1023;80端口分配给HTTP服务;21端口分配给FTP服务

  • 网络传输协议:

 udp和tcp都是网络传输的协议,只不过具体传输形式不一样,但功能都是定义网络传输数据规则。

根据TCP/IP协议簇功能的不同,将它分为了几种层次:

 

                    网络接口层(链路层)                                          物理层

                    网络层                                                                  数据链路层

                    传输层                                                                  网络层

                    应用层                                                                  传输层

                                                                                                会话层

                                                                                                表示层

                                                                                                应用层

 

             网络传输三个必要的前置条件:ip地址,协议,端口

Socket-UDP编程-简介

socket:通过网络完成进程间通信的方式

1、Socket本质是编程接口(API): Socket 是对 TCP/IP 协议的封装

套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认

2.创建socket

import  socket      #导入套接字模块

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

该函数带有两个参数(参数必须写) :AF_INET(ipv4协议于 Internet 进程间通信)

套接字类型: SOCK_STREAM(流式套接字,用于TCP 协议)

                      SOCK_DGRAM(数据报套接字, 用于 UDP 协议)

确定了IP地址端口号(ipv4协议),TCP或UDP协议之后,计算机之间可以进行通信

3 互联网协议簇

UDP --- User Data Protocol,用户数据报协议

TCP --- Transmission Control Protocol,传输控制协议

4.Socket编程-udp编程

发送数据

          from socket import *

          s = socket(AF_INET, SOCK_DGRAM) #创建套接字

          addr = ('192.168.1.17', 8080) #准备接收方地址

          data = input("请输入:")

          s.sendto(data.encode(),addr) #发送数据时,python3需要将字符串转成byte #encode(‘utf-8’)# 用utf-8对数据进行编码,获得bytes类型对象 #decode()反过来

         s.close()

接收数据

         from socket import * s = socket(AF_INET, SOCK_DGRAM) #创建套接字

   addr = ('192.168.1.17', 8080) #准备接收方地址

   data = input("请输入:")

   s.sendto(data.encode(),addr) #等待接收数据

   redata = s.recvfrom(1024) #1024表示本次接收的最大字节数

   print(redata)

   s.close()

5.TFTP(Trivial File Transfer Protocol,简单文件传输协议)

使用这个协议,就可以实现简单文件的下载   tftp端口号为69

  • TFTP格式要求

  • 构造下载请求数据:“1test.jpg0octet0”

import struct

cmb_buf = struct.pack(“!H8sb5sb”,1,b“test.jpg”,0,b“octet”,0)

!H8sb5sb: ! 表示按照网络传输数据要求的形式来组织数据(占位的格式)

H 表示将后面的 1 替换成占两个字节

8s 相当于8个s(ssssssss)占8个字节

b 占一个字节

  • struct模块使用

struct模块可以按照指定格式将Python数据转换为字符串,该字符串为字节流

struct模块中最重要的三个函数是pack(), unpack(), calcsize()

 按照给定的格式(fmt),把数据封装成字符串(实际上是类似于c结构体的字节流):pack(fmt, v1, v2, ...) 

 按照给定的格式(fmt)解析字节流string,返回解析出来的元组:unpack(fmt, string)

 计算给定的格式(fmt)占用多少字节的内存:calcsize(fmt)

  • TFTP下载器

  import struct
  from socket import *
  filename = 'test1.jpg'
  server_ip = '192.168.1.3'
  send_data = struct.pack('!H%dsb5sb' % len(filename), 1, filename.encode(), 0, 'octet'.encode(), 0)
  s = socket(AF_INET, SOCK_DGRAM)
  s.sendto(send_data, (server_ip, 69)) # 第一次发送, 连接服务器69端口
  f = open(filename, 'ab') #a:以追加模式打开(必要时可以创建)append;b:表示二进制
  while True:
  recv_data = s.recvfrom(1024) # 接收数据
  caozuoma, ack_num = struct.unpack('!HH', recv_data[0][:4]) # 获取数据块编号
  rand_port = recv_data[1][1] # 获取服务器的随机端口

  if int(caozuoma) == 5:
  print('文件不存在...')
  break
  print("操作码:%d,ACK:%d,服务器随机端口:%d,数据长度:%d"%(caozuoma, ack_num, rand_port, len(recv_data[0])))
  f.write(recv_data[0][4:])#将数据写入
  if len(recv_data[0]) < 516:
  break
  ack_data = struct.pack("!HH", 4, ack_num)
  s.sendto(ack_data, (server_ip, rand_port)) # 回复ACK确认包

udp 广播

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #对这个需要发送广播数据的套接字进行修改设置,否则不能发送广播数据

s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #允许s发送广播数据 

代码实现广播

  import socket
  dest = (‘<broadcast>’,7788)#<broadcast>自动识别当前网络的广播地址
  #创建udp套接字
  s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  #对这个需要发送广播数据的套接字进行修改设置,否则不能发送广播数据
  s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #允许s发送广播数据
  #setsocketopt 设置套接字选项
  #以广播形式发送数据到本网络的所有电脑中
  s.sendto(b'Hi',dest)
  print("等待回复")
  while True:
  (buf, address) = s.recvfrom(2048)
  print(address,buf.decode(“GB2312”))

Socket-tcp编程-简介

1.TCP:传输控制协议

TCP通信模型: 在通信之前,必须先等待建立链接

 

2 . 三次握手

3. 四次挥手

TCP服务器

  from socket import *
  tcpSerSocket = socket(AF_INET, SOCK_STREAM)
  address = ("", 7788)
  tcpSerSocket.bind(address)
  tcpSerSocket.listen(5)#设置最大连接数
  newSocket, clientAddr = tcpSerSocket.accept()
      # 如果有新的客户端来链接服务器, 那么就产创建个新的套接字
        # newSocket来为这个客户端服务
        # tcpSerSocket就可以省下来等待其他新客户端的链接 
  recvData = newSocket.recv(1024)# 接收对方发送过来的数据, 最大接收1024个字节
  newSocket.send("thank you!")
  newSocket.close()
  tcpSerSocket.close()

 TCP客户端

  from socket import *
  clientSocket = socket(AF_INET, SOCK_STREAM)

  serAddr = ('192.168.1.17', 7788)#链接服务器
  
  clientSocket.connect(serAddr)

  clientSocket.send(b"hello")
  recvData = clientSocket.recv(1024)
  print("接收到的数据为:", recvData)
  clientSocket.close()

 

并发网络服务器

 

from socket import *
from multiprocessing import *
from time import sleep

 

def dealWithClient(newSocket,destAddr):
  while True:
    recvData = newSocket.recv(1024)
    if len(recvData)>0:

      print(recvData)
    else:
      print("客户端关闭")
      break
    newSocket.close()
def main():
  serSocket = socket(AF_INET,SOCK_STREAM)
  serSocket.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
  localAddr = ("",7788)
  serSocket.bind(localAddr)
  serSocket.listen(5)
  try:
    while True:
      print("主进程等待连接")
      newSocket,destAddr = serSocket.accept()
      client = Process(target=dealWithClient,args=(newSocket,destAddr))     
      client.start()
      newSocket.close()
  finally:
    serSocket.close()
if __name__ == "__main__":
  main()

 

转载于:https://www.cnblogs.com/hyt19911004/p/11320820.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值