eight day 2-----网络编程

一、网络编程
1.为什么要有网络编程??
2.两个文件之间如何实现通信?
基于文件通信--两个程序都在同一台机器上
两个不同机器如何通信?

一个局域网的通信依靠交换机
网卡-mac-全球唯一
临时的地址:ip地址
ip网段:4位点分十进制:0.0.0.0-255.255.255.255 ip地址的范围 IPV4协议
    同一网段:通过交换机;不同网段,通过路由器来找

交换机支持三种通信机制:广播、单播、组播
通过ip地址找到mac地址的过程--arp协议(广播,通过ip,满足条件的ip地址,单播回复mac地址)
mac地址是永久的唯一的
ip地址能够找到网络中的唯一一台机器

# 交换机是用于在一个局域网内的机器之间的通信
# 路由器是用于不同局域网之间的机器的通信

arp协议;一台机器通过ip地址和交换机找到另一台机器的mac地址的过程

ip地址能够找到网络中的唯一一台机器,临时的

如何在一台机器上精准的找到要和我通信的服务?
端口 0-65535 一般用8000以后的端口
在一台机器上 ,每一个服务所使用的端口不能相同
通过 ip+port 能够找到网络世界里的一个服务

两种通信协议:
TCP协议;全双工通信、高可靠性的通讯机制 三次握手 保证数据的完整性,不会在网络上丢失
四次挥手,,记住图。。抓包
UDP:速度快,不可靠的通信机制--qq、微信即时通信类的服务 可以加回执机制-实现了相对可靠

互联网协议,物理设备,掌握5层协议
 1 # 为什么要有网络编程???
 2 # 两个文件之间如何实现通信?
 3 # 基于文件通信  —— 两个程序都在同一台机器上
 4 # 两个不同机器上的程序如何实现通信?
 5 # 基于网络
 6 
 7 # mac地址是永久的 唯一的
 8 # 交换机是用于在一个局域网内的机器之间的通信
 9 # 路由器是用于不同局域网之间的机器的通信
10 # arp协议:一台机器通过IP地址和交换机找到另一台机器的mac地址的过程
11 
12 # ip地址能够找到网络中的唯一一台机器,临时的
13 
14 # 如何在一台机器上精准的找到要和我通信的服务???
15 # 端口 0-65535 8000—>
16 # 在一台机器上 每一个服务所使用的端口不能相同
17 
18 # 通过什么能够找到网络世界里的一个服务? ip+端口
19 # 两种通信协议
20     # TCP、UDP
21 # 网络编程
View Code

 

互联网协议与osi模型

 

互联网协议按照功能不同分为osi七层或tcp/ip五层或tcp/ip四层

 

 

每层运行常见物理设备

 

 

 

 

每层运行常见的协议

 

 

二、socket

1.socket概念
socket(套接字)

tcp建立连接后,同一时刻不能和两个终端进行通信 2个whiletrue
 1 import socket
 2 
 3 sk=socket.socket()  #拿到一个socket实例化对象
 4 sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)  ##加入一条socket配置,重用ip和端口
 5 sk.bind(('127.0.0.1',9000))
 6 sk.listen()  #监听
 7 while True:#无限的接电话
 8     conn,addr = sk.accept() #等待来电 三次握手完毕
 9     # print(addr)
10     # conn.send(b'hello')    #发送数据
11     # print(conn.recv(1024))   #接收数据
12     while True:  #接到电话之后无限聊
13         msg = input('>>>')
14         conn.send(msg.encode('utf-8'))  # 发送数据
15         if msg == 'q': break
16         ret=conn.recv(1024).decode('utf-8')
17         if ret=='q':break
18         print(ret)
19 
20     conn.close()
21 
22 sk.close()
server-tcp
 1 import socket
 2 sk=socket.socket()
 3 
 4 sk.connect(('127.0.0.1',9000)) #元祖
 5 
 6 # print(sk.recv(1024).decode('utf-8')) #接收一个数据,1024表示阻塞 最大接收1024个字节
 7 # sk.send(b'byebye')
 8 while True:
 9     ret=sk.recv(1024).decode('utf-8')
10     if ret=='q':break
11     print(ret)
12     msg = input('client输入>>>')
13     sk.send(msg.encode('utf-8'))
14     if msg=='q':break
15 sk.close()
client-tcp

udp server发送要写地址,,,udp能够实现并发,能收到多个client收到的信息 1个whiletrue
tcp 不写参数
 1 import socket
 2 sk=socket.socket(type=socket.SOCK_DGRAM)
 3 sk.bind(('127.0.0.1',8899))
 4 while True:
 5     msg,addr=sk.recvfrom(1024)
 6     print(addr,msg.decode('utf-8'))
 7     inp = input('>>>')
 8     #sk.sendto(b'byebye',addr)
 9     sk.sendto(inp.encode('utf-8'),addr)
10 
11 sk.close()
server--udp
1 import socket
2 sk=socket.socket(type=socket.SOCK_DGRAM)
3 while True:
4     inp=input('client>>>')
5     # sk.sendto(b'hello',('127.0.0.1',8899))
6     sk.sendto(inp.encode('utf-8'),('127.0.0.1',8899))
7     msg,addr=sk.recvfrom(1024)
8     print(msg.decode('utf-8'))
9 sk.close()
client--udp

黏包:发送的两条数据,黏在了一起,只发生在tcp协议中
在连续send的过程中,就容易发生黏包现象

udp信息有长度限制(最大65535-ip头(20)-udp头(8)=65507个),tcp没有!
tcp协议的拆包机制 面向流的通信特点和Nagle算法 缓存

ftp上传下载文件

解决粘包问题:1.设置长度2.使用struct模块--无论多大,都能转成4位的
struct unpack返回只有一个元素的元祖,取值时取第一个元素即可,res[0]

书写发送字典的例子。
 1 import socket
 2 import struct
 3 sk = socket.socket()
 4 sk.bind(('127.0.0.1',8080))
 5 sk.listen()
 6 
 7 conn,addr = sk.accept()
 8 inp = input('>>>').encode('utf-8')
 9 inp_len = len(inp)
10 bytes_msg = struct.pack('i',inp_len)
11 conn.send(bytes_msg)
12 conn.send(inp)
13 conn.send(b'alex sb')
14 
15 conn.close()
16 sk.close()
解决粘包-server
 1 import socket
 2 import struct
 3 sk = socket.socket()
 4 sk.connect(('127.0.0.1',8080))
 5 num = sk.recv(4)
 6 num = struct.unpack('i',num)[0]
 7 print(sk.recv(num))
 8 print(sk.recv(10))
 9 # dic = {'filename':'client','filesize':'os.path.getsize('路径')'}
10 # str_dic = json.dumps(dic).encode('utf-8')
11 # len(str_dic)
12 # struct.pack()
13 # dic_len = send(dic_len)
14 # send(str_dic)
15 sk.close()
解决粘包-client

 

posted @ 2018-05-29 21:10  yuyou123  阅读(119)  评论(0编辑  收藏  举报