网络编程--1
一、TCP/IP协议簇
早期的计算机⽹络,都是由各⼚商⾃⼰规定⼀套协议,IBM、Apple和 Microsoft都有各⾃的⽹络协议,互不兼容
为了把全世界的所有不同类型的计算机都连接起来,就必须规定⼀套全球通 ⽤的协议,为了实现互联⽹这个⽬标,互联⽹协议簇(Internet Protocol Suite)就是通⽤协议标准。
因为互联⽹协议包含了上百种协议标准,但是最重要的两个协议是TCP和IP 协议,所以,⼤家把互联⽹的协议简称TCP/IP协议
按4层划分:链路层,网络层,传输层,应用层
按7层划分:物理层,数据链路层,网络层,传输层,会话层,表示层,应用层
二、端口
1.端口号
端口是通过端口号来标记的,端口号只有整数。范围是从0到65535
2.知名端口
范围:0-1023
80端口分配给HTTP
21端口分配给FTP
3.动态端口
范围:1024-65535
之所以称为动态端⼝,是因为它⼀般不固定分配某种服务,⽽是动态分配。
动态分配是指当⼀个系统进程或应⽤程序进程需要⽹络通信时,它向主机申 请⼀个端⼝,主机从可⽤的端⼝号中分配⼀个供它使⽤。
当这个进程关闭时,同时也就释放了所占⽤的端⼝号。
三、IP地址
1.A类IP地址:
⼀个A类IP地址由1字节的⽹络地址和3字节主机地址组成,⽹络地址的最⾼ 位必须是“0”,
地址范围1.0.0.1-126.255.255.254
⼆进制表示为:00000001 00000000 00000000 00000001 - 01111110 11111111 11111111 11111110
可⽤的A类⽹络有126个,每个⽹络能容纳1677214个主机
2.B类IP地址:
⼀个B类IP地址由2个字节的⽹络地址和2个字节的主机地址组成,⽹络地址 的最⾼位必须是“10”,
地址范围128.1.0.1-191.255.255.254
⼆进制表示为:10000000 00000001 00000000 00000001 - 10111111 11111111 11111111 11111110
可⽤的B类⽹络有16384个,每个⽹络能容纳65534主机
3.C类IP地址:
⼀个C类IP地址由3字节的⽹络地址和1字节的主机地址组成,⽹络地址的最 ⾼位必须是“110”
范围192.0.1.1-223.255.255.254
⼆进制表示为: 11000000 00000000 00000001 00000001 - 11011111 11111111 11111110 11111110
C类⽹络可达2097152个,每个⽹络能容纳254个主机
4.D类IP地址:(用于多点广播)
D类IP地址第⼀个字节以“1110”开始,它是⼀个专⻔保留的地址。
它并不指向特定的⽹络,⽬前这⼀类地址被⽤在多点⼴播(Multicast)中
多点⼴播地址⽤来⼀次寻址⼀组计算机
地址范围224.0.0.1-239.255.255.254
5.E类IP地址:
以“1111”开始,为将来使⽤保留
E类地址保留,仅作实验和开发⽤
6.私有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
7.注意
IP地址127.0.0.1~127.255.255.255⽤于回路测试,
如:127.0.0.1可以代表本机IP地址,⽤ http://127.0.0.1 就可以测试本机 中配置的Web服务器。
四、socket
socket(简称 套接字 ) 是进程间通信的⼀种⽅式
1.创建socket
UDP:SOCK_DGRAM
TCP:SOCK_STREAM
import socket s = socket.socket(socket.AF_IFET,socket.SOCK_STREAM/SOCK_DGRAM) print = (Socket Created)
五、UDP
UDP是⾯向⽆连接的通讯协议,UDP数据包括⽬的端⼝号和源端⼝号信息, 由于通讯不需要连接,所以可以实现⼴播发送。 UDP传输数据时有⼤⼩限 制,每个被传输的数据报必须限定在64KB之内。 UDP是⼀个不可靠的协 议,发送⽅所发送的数据报并不⼀定以相同的次序到达接收⽅。
1.udp网络程序--发送数据
from socket import * #1.创建套接字 udpSocket = socket(AF_INET,SOCK_DGRAM) #2.准备接收⽅的地址 sendAddr = ('192.168.1.103',8080) #3.从键盘获取数据 sendData =raw_input("请输⼊要发送的数据:") #4.发送数据到指定的电脑上 udpSocket.sendto(sendData,sendAddr) #5.关闭套接字 udpSocket.close()
2.udp网络程序--接收数据
#coding=utf-8 from socket import * #1.创建套接字 udpSocket=socket(AF_INET,SOCK_DGRAM) #2.准备接收⽅的地址 sendAddr=('192.168.1.103',8080) #3.从键盘获取数据 sendData=raw_input("请输⼊要发送的数据:") #4.发送数据到指定的电脑上 udpSocket.sendto(sendData,sendAddr) #5.等待接收对⽅发送的数据 recvData=udpSocket.recvfrom(1024) #1024表示本次接收的最⼤字节数 #6.显示对⽅发送的数据 print(recvData) #7.关闭套接字 udpSocket.close()
3.udp绑定信息
#coding=utf-8 from socket import * #1. 创建套接字 udpSocket = socket(AF_INET, SOCK_DGRAM) #2. 绑定本地的相关信息,如果⼀个⽹络程序不绑定,则系统会随机分配 bindAddr = ('', 7788) # ip地址和端⼝号,ip⼀般不⽤写,表示本机的任何⼀个ip udpSocket.bind(bindAddr) #3. 等待接收对⽅发送的数据 recvData = udpSocket.recvfrom(1024) # 1024表示本次接收的最⼤字节数 #4. 显示接收到的数据 print recvData #5. 关闭套接字 udpSocket.close()
4.echo服务器
#coding=utf-8 from socket import * #1. 创建套接字 udpSocket = socket(AF_INET, SOCK_DGRAM) #2. 绑定本地的相关信息 bindAddr = ('', 7788) # ip地址和端⼝号,ip⼀般不⽤写,表示本机的任何⼀个ip udpSocket.bind(bindAddr) num = 1 while True: #3. 等待接收对⽅发送的数据 recvData = udpSocket.recvfrom(1024) # 1024表示本次接收的最⼤字节数 #4. 将接收到的数据再发送给对⽅ udpSocket.sendto(recvData[0], recvData[1]) #5. 统计信息 print('已经将接收到的第%d个数据返回给对⽅,内容为:%s'%(num,recvData[ num+=1 #5. 关闭套接字 udpSocket.close()
5.全双工飞秋聊天程序
import socket,threading # 发送数据 def send(): while True: sendData = input("---") sendData = sendData.encode("gb2312") udpSocket.sendto(sendData,(sendAddr,iport)) # 接收数据 def recv1(): while True: recvData = udpSocket.recvfrom(1024) print(recvData[0].decode("gb2312"))
# 定义全局变量 udpSocket = None sendAddr = "" iport = 0 def main1(): global sendAddr global iport global udpSocket global lock1 udpSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) udpSocket.bind(("", 7878)) sendAddr = input("请输入IP:") iport = int(input("请输入端口号:"))
#创建多线程 t1 = threading.Thread(target=send) t2 = threading.Thread(target=recv1) t1.start() t2.start() if __name__ == "__main__": main1()
六、TFTP
TFTP客户端--向服务器请求下载
import struct,socket
# 创建套接字 udpSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) IP = "192.168.2.45" filename = "test.jpg"
# 构建下载请求数据 cmd_buf = struct.pack("!H8sb5sb",1,filename.encode(),0,"octet".encode(),0) sendAddr = (IP,69)
# 发送数据 udpSocket.sendto(cmd_buf,sendAddr)
# 打开下载文件 f = open(filename,"ab")
while Turn:
# 接收数据 recvData = udpSocket.recvfrom(1024)
# 获取数据块编号 opcode,ack_num = struct.unpack("!HH",recvData[0][:4])
# 获取服务器的随机端口 rand_port = recvData[1][1]
# 判断操作码是否错误 if int(opcode) == 5: print("文件不存在...") break print("操作码:%d,ACK:%d,服务器随机端口号:%d,数据长度:%d"%(Opcode, ack_num, rand_port, len(recvData[0])))
# 写入数据 f.write(reccvData[0][4:]) if len(recvData[0]) < 516 break ack_data = struct.pack("!HH",4,ack_num)
# 回复ACK确认包 udpSocket.sendto(ack_data,(IP,rand_port))