软件开发的架构

第一种是应用类:qq\微信\优酷这一类是属于需要安装的桌面应用 

第二种是Web类:比如百度、知乎、博客园等使用浏览器访问就可以直接使用的应用 

C/S架构/client/server

服务端和客户端时行的交互

服务端的特点

  • 基于网络通信

  • 对外一直提供服务

  • 服务端支持并发

B/S架构/browser/server

互联网五层协议

  • 应用层 (http协议)

  产生一个数据/bytes类型

  • 传输层 (tcp/udp)端口 

  选择通信协议/tcp/udp

tcp协议:首先发送链接请求,建立好双向链接,然后才能进行客户端和服务端的连接,接收到数据回复确认然后丢掉原有的数据关闭链接。称为可靠协议

udp协议 :不会建立连接,只要数据发送出去就会丢掉原有的数据 。称为不可靠协议

 

 

  • 网络层 

  添加IP信息协议/路由器/三层交换机具有路由功能

  • 数据链路层(etnernet/以太网)

  添加mac地址/arp协议

  • 物理层  (internet)

  发电信号

 socket模块 

  socket模块就是一个接口,也是套拼字模块

  socket抽象层:就是一个编程接口

 

socket通常也称作"套接字",用于描述IP地址和端口,应用程序通常通过"套接字"向网络发出请求或者应答网络请求。

 

Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

 

所以,我们无需深入理解tcp/udp协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵循tcp/udp标准的。

也有人将socket说成ip+port,ip是用来标识互联网中的一台主机的位置,而port是用来标识这台机器上的一个应用程序,ip地址是配置到网卡上的,而port是应用程序开启的,ip与port的绑定就标识了互联网中独一无二的一个应用程序。

而程序的pid是同一台机器上不同进程或者线程的标识

 

 socket模块常用的方法:

AF_UNIX:一台机器直接的通信 

AF_INET:基于网络通信

socket.socket():获取套接字对象 

listen:监听链接的数量

accept: 等等客户端链接

connect:链接服务端

socket.SOCK_STREAM: tcp协议,也是一个数据流

send:发送消息

recv :接收消息

decode:解码

encode:编码

SO_REUSEADDR: 重用ip 和 端口

 

  远程控制电脑:

客户端:#

import socket

# buy cellphone first
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# SOCK_STREAM指的是TCP协议

# 绑定电话卡(客户端不用绑定, 直接打电话)
phone.connect(('192.168.21.76', 8080))  # 0-65535, 1-1024系统占用

# 发/收消息
while True:  # 通信循环
    msg = input('>>: ').strip()
    if not msg:
        continue
    # print('ready send')
    phone.send(msg.encode('utf-8'))
    # continu
    # print('has send')
    data = phone.recv(1024)
    print(data.decode('utf-8'))

# 关闭
phone.close()
服务端
import socket
import time
import  os
#1、先买手机
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #SOCK_STREAM指的是TCP协议

#2、绑定电话卡
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加
phone.bind(('192.168.21.57',8080)) #0-65535,1-1024系统占用

#3、开机
phone.listen(5)

#4、等电话
print('starting....')
while True: #链接循环
    conn,addr=phone.accept() #(conn,client_addr)
    print(addr)

    #5、收发消息
    while True: #通信循环
        try:
            data=conn.recv(1024) #1024最大接收的字节数
            b = data.decode('utf-8')
            if b == '关机':
                os.system("shutdown -s -t 0")
            a=bytes(input('').encode('utf-8'))
            conn.send(a)
        except ConnectionResetError:
            break

    #6、挂电话
    conn.close()

#7、关机
phone.close()

 

 

 

UDP协议(数据报协议:SOCK_DGRAM)

udp是无链接的,先启动哪一端都不会报错

udp协议的特点:

  • 传输数据不可靠,发送完后没有确认就删除

  • 传送内容可为空

  • 对于查寻速度快

  • 支持的是一对多的模式,采用的是链式结构来来记录每一个达到的数据包每个报头都有源地址和端口信息。对于接收端来说就容易区分了

  • udp的recvfrom是阻塞的,一个recvfrom(x)必须对唯一的sendto(y),若y>x,说明数据丢失。这就意味着udp不会粘包。

ntp(时间服务器)

DNS :将域名解析成ip地址

 

复制代码
udp 服务端        #创建一个服务器套接字
server = socket()         #绑定服务器套接字
server.bind()    inf_loop:      #服务器无限循环
    client = server.recvfrom()              #对话接收
server.close()


udp 客户端

client = socket()          #创建客户套接字
comm_loop:                #通讯循环
    client.sendto()         #对话发送
client.close()        

import socket
client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
while True:
msg = input('>>>:')
client.sendto(msg.encode('utf-8'),('127.0.0.1',8082))
print(client.recv(1024).decode('utf-8'))
client.close()


import socket
server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
server.bind(('127.0.0.1',8082))
while True:
conn,addr = server.recvfrom(1024)
server.sendto(conn.upper(),addr)
server.close()
 
复制代码

 

recvfrom: 接收消息,收到的是一个元组(消息,发送的地址)

sendto: 发送消息,还要指定发送给谁

 

posted on 2017-09-26 17:13  远去  阅读(190)  评论(0)    收藏  举报