网络编程

2018-09-15

1:软件开发的架构

两件程序之间通讯的应用大致可以分为两种:

第一种:qq. 微信,网盘,优酷 这一类是属于需要安装的桌面应用
第二种:比如百度, 知乎,博客园之类

c/s架构

即Client 与 Server, 客户端与服务器的端架构

b/s架构

Browser 与 Serverm 浏览器与服务端架构

IP地址

1: 网卡 :身份证 mac地址 计算机在网络上的身份证
2: 交换机 :负责一个网络内的多台机器之间的信息交换
3: mac地址 :16进制的数  全球唯一

1: 127.0.0.1 :本地回环地址 本机的地址
2: 0.0.0.0 : ip地址的、回环地址的所有的用户都能找到你这台机器

局域网

# 局域网
1: 网关ip    不同局域网之间通信依赖的ip地址
2: 子网掩码  判断两个ip地址是否在同一个网段内
3:网段


# 0.0.0.0 - 255.255.255.255
# 局域网的概念
# 外网ip 我们谁都能访问
# 内网ip 从外部不能访问,只能在内部环境中互相访问
# 外网ip永远不会和内网ip冲突?
# 0.0.0.0 - 255.255.255.255中间为内网保留了一些字段
# 192.168.0.0 - 192.168.255.255
# 10.0.0.0 - 10.255.255.255
# 172.16.0.0 - 172.31.255.255

局域网中两台机器的通信原理

局域网中两台机器的通信原理

# 交换机
# ip地址
# ip地址 -arp协议-> mac地址
# mac地址 : 全球唯一
# arp协议 : 广播 和 单播
    # 通过ip地址获取mac地址
    # 一台机器A发起一个arp请求(只包含ip地址),发送给交换机
    # 交换机接收到请求,广播这条消息
    # 所有的机器都会接收到这个请求,只有和要寻找ip地址吻合的机器B
    # 才会回应交换机的广播,(带着自己的mac地址)
    # 交换机通过单播的形式将回复的B的mac地址发送给A
# 判断两台机器是不是在同一个局域网内:
    # 子网掩码
    # A机器的ip地址和A的子网掩码 按位与
    # B机器的ip地址和B的子网掩码 按位与
    # 得到的结果如果一致 那么说明两台机器是在一个网段内的

端口

# 端口的概念 —— 帮助你找到一个应用
# 每一个网络服务都会占用计算机上的一个端口
# 计算机上的端口范围 0-65535
# 在同一时刻 同一台计算机上 不同的网络应用 占用的端口一定是不同的

2:OSI 七层模型

在7层的基础上简化为5层

# 应用层 http、https
# 传输层 TCP、UDP协议
        # 端口 :找到某一台机器上的具体的网络应用
        # tcp 面向连接 可靠 慢 全双工
            # 三次握手 建立tcp连接的过程
            # 发消息
            # 四次挥手 断开tcp连接的过程
           # udp 无连接 不可靠 快

# 网络层 ip协议
# 数据链路层 arp协议
# 物理层

Tcp 和 Udp

tcp 面向连接的 可靠的 但是慢

# tcp协议
# 两个应用之间要想通信 必须先建立连接
# 然后基于连接来通信
# 比较重要的文件 邮件的发送 下载安装包

udp 无连接的 快 能够发送的信息长度是有限的

# 快 但 不可靠 不能发送过长的数据
# 即时通讯类的程序

tcp和udp 的区别

 tcp、udp是通过网络通信的两种方式
   tcp 先建立连接再通信
        # 可靠
        # 慢
    udp 不需要建立连接直接通信
        # 快
        # 不可靠

一个简单的tcp: server 和 client

sever

from socket import *
ip_port = ('127.0.0.1', 9514)

sk = socket(AF_INET, SOCK_STREAM)
sk.bind(ip_port)
sk.listen()
sk_cl, addr = sk.accept()
data1 = sk_cl.recv(10)
data2 = sk_cl.recv(10)

print('----->', data1.decode('utf-8'))
print('----->', data2.decode('utf-8'))

sk_cl.close()

client

from socket import *
ip_port = ('127.0.0.1', 9514)

sk = socket(AF_INET, SOCK_STREAM)
sk.connect(ip_port)

sk.send(b'my name is leiwenxuan')
sk.send(b'nsdfasfdsf')

udp的简单程序

sever

import socket
sk = socket.socket(type=socket.SOCK_DGRAM)

sk.bind(('127.0.0.1', 9000))
while 1:
    msg,addr = sk.recvfrom(1024)
    print(msg.decode('utf-8'), addr)
    # sk.sendto('正在发送...'.encode('utf-8'), addr)
    inp = input('input :')

client

import socket

sk = socket.socket(type=socket.SOCK_DGRAM)
sk.bind(('127.0.0.1', 9001))

while 1:
    # sk.sendto('正在发送...'.encode('utf-8'), ('127.0.0.1', 9000))
    inp = input('input:')
    sk.sendto(inp.encode('utf-8'),('127.0.0.1', 9000) )
    msg, addr = sk.recvfrom(1024)
    print(msg.decode('utf-8'), addr[1])

一个重要的黏包处理

server

import json, struct
'''传输一个简单的文件'''
import os
from socket import *
path_name = r'G:\python笔记\Pythonjing\day31\video\1.内容回顾和作业讲解.mp4'
path_name = os.path.realpath(path_name)
size = str(os.path.getsize(path_name))

ip_port = ('127.0.0.1', 9514)
sk = socket(AF_INET, SOCK_STREAM)
sk.bind(ip_port)
sk.listen()
sk_cl, addr = sk.accept()

sk_cl.send(size.encode('utf-8'))
with open(path_name, 'rb') as f:
    while 1:
        data = f.read(2048)
        pack_num = struct.pack('i', len(data))
        sk_cl.send(pack_num)
        sk_cl.send(data)
        if not data:
            pack_num = struct.pack('i', len(''))
            sk_cl.send(pack_num)
            print(len(data))
            break

client

from socket import *
import struct
import sys


def processBar(num, total):
    '''进度条'''
    rate = num / total
    rate_num = int(rate * 100)
    if rate_num == 100:
        r = '\r%s>%d%%\n' % ('|' * rate_num, rate_num,)
    else:
        r = '\r%s>%d%%' % ('|' * rate_num, rate_num,)
    sys.stdout.write(r)
    sys.stdout.flush


ip_port = ('127.0.0.1', 9514)
sk = socket(AF_INET, SOCK_STREAM)
sk.connect(ip_port)


size = int(sk.recv(1024).decode('utf-8'))
# processBar(2048, size)
num_size = 0
with open('lw.mp4','wb') as f:
    while 1:
        pack_num = sk.recv(4)
        num = struct.unpack('i', pack_num)[0]
        # print(num)
        if not num:
            break
        ret = sk.recv(num)
        f.write(ret)
        num_size += num
        processBar(num_size, size)

 

posted @ 2018-09-15 16:50  雷文轩  阅读(120)  评论(0编辑  收藏  举报