标签:soc 列表 mac 获取 alt cte net write 广播
TCP/IP协议
一、层次划分:
层次:链路层==>网络层==>传输层==>应用层
理论层次:物理层==>数据链路层==>网络层==>传输层==>会话层==>表示层==>应用层
应用层:解决要传递什么数据
传输层:解决如何传输数据,udp/tcp
网络层:解决地址问题,IP
链路层:具体传输工具
二、UDP(用户数据包协议),注重速度,不够稳定
#创建客户端从服务器上下载文件
#coding=utf-8
from socket import *
import struct
import sys
if len(sys.argv) != 2:
print(‘-‘*30)
print("tips:")
print("python xxxx.py 192.168.1.1")
print(‘-‘*30)
exit()
else:
ip = sys.argv[1]
# 创建udp套接字
udpSocket = socket(AF_INET, SOCK_DGRAM)
#构造下载请求数据
cmd_buf = struct.pack("!H8sb5sb",1,"test.jpg",0,"octet",0)
#发送下载文件请求数据到指定服务器
sendAddr = (ip, 69)
udpSocket.sendto(cmd_buf, sendAddr)
p_num = 0
recvFile = ‘‘
while True:
recvData,recvAddr = udpSocket.recvfrom(1024)
recvDataLen = len(recvData)
cmdTuple = struct.unpack("!HH", recvData[:4])
#得到操作号与数据包编号
cmd = cmdTuple[0]
currentPackNum = cmdTuple[1]
if cmd == 3: #是否为数据包
# 如果是第一次接收到数据,那么就创建文件
if currentPackNum == 1:
recvFile = open("test.jpg", "a")
# 包编号是否和上次相等
if p_num+1 == currentPackNum:
recvFile.write(recvData[4:]);
p_num +=1
print ‘(%d)次接收到的数据‘%(p_num)
ackBuf = struct.pack("!HH",4,p_num)
udpSocket.sendto(ackBuf, recvAddr)
# 如果收到的数据小于516则认为出错
if recvDataLen<516:
recvFile.close()
print ‘已经成功下载!!!‘
break
elif cmd == 5: #是否为错误应答
print "error num:%d"%currentPackNum
break
udpSocket.close()
UDP广播(只有udp能用)
import socket
dest = (‘<broadcast>‘,端口号)
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#使用广播时固定调用这句话
s.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1)
s.sendto(‘hi‘,dest)
三、TCP(传输控制协议)
数据传输稳定,略慢于udp,web 服务器都是使用tcp
1、tcp服务器
from socket import *
serverSocket = socket(AF_INET,SOCK_STREAM)
serverSocket.bind((‘‘,7788))
serverSocket.listen(5)
#accept()返回值是一个元组
#clientSocket 表示这个新的客户端
#clientInfo 表示新客户端的IP和port
clientSocket,clientInfo = serverSocket.accept()
recvData = clientSocket.recv(1024)
print(‘%s:%s‘%(str(clientInfo),recvData))
clientSocket.close()
serverSocket.close()
2、tcp客户端
manSocket = socket(AF_INET,SOCK_STREAM)
manSocker.connect((‘客户端IP‘,4567))
sendData = imput(‘请输入要传输的信息:‘)
#tcp已经链接好了服务器,所以发数据不用再写IP和port
#udp因为没有事先链接,所以每次发送都要写IP和port
manSocker.send(sendData.encode(‘gb2312‘))
recvData = manSocker.recv(1024)
print(‘recvData:%s‘%recvData.decode(‘gb2312‘))
manSocker.close()
3、单进程服务器完成伪并发
#select,最多1024个元素,用轮询方式检测
#poll,解决了套接字上限的问题,轮询方式检测
#epoll,没有上限,事件通知机制
from socket import *
import select
server = socket(AF_INET,SOCK_STREAM)
server.bind((‘‘,7788))
server.listen(1000)
list = [server]
while True:
#linux 中,select通过底层直接分别筛选三个列表,筛选条件分别为可接收数据,可发送数据,有异常信息
#没有更新信息时默认堵塞,有新客户访问或已有客户发信息时解堵塞
recvableList,list2,list3 = select.select(list,[],[])
for i in recvableList:
#有新的客户端访问时,服务端创建新的socket,并放入列表,等待下次循环筛选
if i == server:
newSocket,socketAddr = server.accept()
list.append(newSocket)
#客户发送信息时,读取发送的数据
else:
recvData = i.recv(1024)
if recvData:
i.send(recvData)
else:
#此时客户端close(),下面移除select监听的i这个socket
list.remove(i)
i.close()
4、其他备注:
a. ip地址和网络掩码按位与操作后,得到网络号,网络号相同则能够相互通信
b. MAC地址,即网卡实际地址,由6个字节的十六进制数(12位)组成,前三字节表示生产厂家,后三位表示生产编号
c. icmp:ping一个电脑
d. arp:根据IP获取一个电脑上的网卡号,就是Mac地址
e. rarp:根据Mac地址找IP
标签:soc 列表 mac 获取 alt cte net write 广播
原文地址:https://www.cnblogs.com/dalun101/p/9367804.html