计算机网络课程设计报告
题目 智能家居协议设计
1 项目描述 1
2 功能分析 1
3 系统设计 1
4 主要功能 3
5 项目的实现 3
6 项目实现结果 7
7 课程设计总结 8
1 项目描述
实现一个基于socket的物联网服务器,接收来自客户端的数据。实现一个物联网客户端,模拟设备。客户端产生数据,发送至服务器,服务器根据协议对数据作出处理。需要模式的设备有:
温度传感器:采集房间温度信息。
湿度传感器:采集房间湿度信息。
空调:可以根据服务器发来的指令进行调节模式(制冷、制热、送风)、设置温度、风速;还可以根据服务器的指令上传子自己的当前状态:模式、温度、风速。
门窗磁:可以根据服务器发来的指令打开或者关闭窗户。
通信规则:
下位机10秒上传心跳,上位机收到后进行答复,答复数据中包含自己的时间;
下位机5秒上传设备信息(温度、湿度、灯光、空调、门窗、插卡取电),上位机收到后进行答复,答复数据中包含自己的时间;
要求:设计通信协议完成数据的双向传输,应用层协议应包含首部和数据部分。
2 功能分析
需要通过Socket完成客户端与服务端的连接通信,设计一种协议,让客户端和服务端进行通信时使用设定的数据报格式,服务器能够根据用户的指令发送给客户端指定的数据报,客户端接受到服务器的数据报后,能够对数据报进行解析,然后根据解析出的命令,对数据报中指定的硬件进行修改和查询状态。客户端每隔5秒向服务端发送数据报来报告给服务端当前的硬件状态,服务端收到后向客户端发送收到确认。在初始时,没插卡的状态下,任何对于硬件的改变都应该无效,还应该实现服务器可以连接多个客户端。
3 系统设计
Socket设计:套接字(socket)是一个抽象层,网络套接字是IP地址与端口的组合。本课设是在Windows环境下配置,网络应用程序编程接口称作Windows Socket。对服务端和客户端配置套接字,格式为[IP:端口号],两个网络应用进程进行通信时,其中的一个网络应用程序将要传输的一段信息写入它所在主机的Socket中,该Socket通过网络接口卡的传输介质将这段信息发送给另一台主机的Socket中,使这段信息能传送到其他程序中。因此,两个应用程序之间的数据传输要通过套接字来完成。
通信协议设计:数据报格式
源地址 目的地址 硬件选择 温度 湿度 灯光 模式 温度 风速 门窗 插卡
数据帧首部:源地址[1位]+目的地址[1位]+设备类型[6位]
源地址 目的地址 代表含义 设备类型 代表含义
0 x(x>0)服务器发送给客户端x 温度传感器 0代表未选中该部件,1代表选中该部件湿度传感器 灯光 x(x>0)0客户端x发送给服务器 空调 门窗磁 插卡区
源地址: 【1位】0表示服务器,1~9分别代表不同的客户端编号。
目的地址:【1位】0代表服务器,1~9分别代表不同的客户端编号
设备类型:【5位】 第1位代表温度传感器,第2位代表湿度传感器,第3位代表灯光,第4位代表空调,第5位代表门窗磁,第6位代表插卡区。
数据部分:温度[2位]+湿度[2位]+灯光[4位]+模式[1位]+温度[2位]+风速[1位]+门窗[1位]+插卡器[1位]
温度 湿度 灯光 空调模式 空调温度 空调风速 门窗状态 是否插卡
温度:【2位】 两位数据来表示当前室内温度
湿度:【2位】 两位数据来表示当前室内湿度
灯光:【4位】 四位数据来代表4个等,每位数据中0表示灯关,1表示灯打开,2表示灯强光,3表示灯最强光
空调模式:【1位】 1位数据分别表示空调的不同模式,0表示关闭,1表示制冷模式,2表示制热模式,3表示送风模式
空调温度:【2位】 来表示当前空调开的温度。
空调风速: 【1位】 0~9分别表示空调风速的等级强度
门窗状态:【1位】 0表示门窗关闭,1表示门窗打开
是否插卡:【1位】 0表示还未插卡,1表示已经插卡
4 主要功能
用户->上位机:用户可以通过上位机给下位机下发控制设备的命令
下位机->用户:用户可以通过向上位机下发命令查看空调的设置状态信息
下位机->设备:下位机可以根据上位机发来的数据报解析后修改或者查询设备的信息
上位机<->下位机:上位机向下位机发送数据报控制硬件,以及收到下位机传来的状态后要发送报文告诉下位机是否成功接收到。下位机每隔5秒需要向上位机反馈当前温度、湿度、灯光、空调、门窗、插卡的一些状态,还要每隔10秒向上位机上床心跳。
5 项目的实现
实现报文解析:
def run(val):
global temperature
global humidity
global light1
global light2
global light3
global light4
global mode
global temperature2
global speed
global is_open
global is_insert
if val[2]==1:
temperature=val[7:9]
elif val[3]==49:
if val[11]<=51:
light1=val[11]-48
if val[12]<=51:
light2=val[12]-48
if val[13]<=51:
light3=val[13]-48
if val[14]<=51:
light4=val[14]-48
elif val[4]==49:
if val[15]==48:
print("空调温度为:%s"%(temperature2))
if mode == 49:
print("空调处于制冷模式" )
if mode == 50:
print("空调处于制热模式")
if mode == 51:
print("空调处于送风模式")
print("空调风速为:%d"%(speed-48))
else:
mode=val[15]
temperature2=(val[16]-48)*10
temperature2=temperature2+val[17]-48
temperature2=str(temperature2)
temperature=temperature2
speed=val[18]
elif val[5]==49:
is_open=val[19]-48
elif val[6]==49:
is_insert=val[20]-48
服务器发送控制命令:
def sendData():
global flag
while True:
for s in aliveConnList:
newSocket=s[0]
chose=input()
chose=int(chose)
msg=""
if chose==1:
msg="100000100000000000001"
elif chose==2:
print("0.关闭灯")
print("1.打开灯")
print("2.灯变亮")
print("3.最大亮度")
cho=str(input())
msg="10010000000"+cho+"555000000"
elif chose==3:
print("0.关闭灯")
print("1.打开灯")
print("2.灯变亮")
print("3.最大亮度")
cho=input()
msg="100100000005"+cho+"55000000"
elif chose==4:
print("0.关闭灯")
print("1.打开灯")
print("2.灯变亮")
print("3.最大亮度")
cho=input()
msg="1001000000055"+cho+"5000000"
elif chose==5:
print("0.关闭灯")
print("1.打开灯")
print("2.灯变亮")
print("3.最大亮度")
cho=input()
msg="10010000000555"+cho+"000000"
elif chose==6:
m=str(input("请输入空调模式:"))
te=str(input("请输入空调温度:"))
sp=str(input("请输入空调风速:"))
msg="100010000000000"+m+te+sp+"00"
elif chose==7:
msg="100010000000000000000"
elif chose==8:
msg="100000100000000000000"
while flag == 1:
pass
flag=1
newSocket.send(msg.encode())
flag=0
6 项目实现结果
7 课程设计总结
本次设计的智能家居协议,利用python编写,学习了很多课外知识,比如:python socket编程,python实现多线程。网络应用程序编程接口称作Socket。使用bind函数绑定端口号和IP地址,connect函数实现套接字连接到目的地址,实现服务端和客户端之间的连接。Listen函数在服务端申请到套接字和调用bind与本地地址绑定后,使用listen函数等待客户机程序的链接。send、recv函数实现发送和接受数据。通过socket通信,传输设计的通信帧实现通信同步。通过本次实验更加了解了物联网,智能家居的工作方式。同时对于课上所学的知识有了更加深刻的认知和了解,对于应用层的数据传输原理以及实现有了了解,对于运输层的数据TCP传输有了更加深入的认识,做到了理论与实践相结合,做出的课设成果有自己的特色。在实践中学到知识,又在实践中验证加深了学过内容。
附录:源程序或关键配置命令
client.py:
from threading import Thread
from socket import *
import time
flag=0
def show():
print(mode)
print(temperature2)
print(speed)
# 接收服务器数据
def run(val):
global temperature
global humidity
global light1
global light2
global light3
global light4
global mode
global temperature2
global speed
global is_open
global is_insert
if val[2]==1:
temperature=val[7:9]
elif val[3]==49:
if val[11]<=51:
light1=val[11]-48
if val[12]<=51:
light2=val[12]-48
if val[13]<=51:
light3=val[13]-48
if val[14]<=51:
light4=val[14]-48
elif val[4]==49:
if val[15]==48:
print("空调温度为:%s"%(temperature2))
if mode == 49:
print("空调处于制冷模式" )
if mode == 50:
print("空调处于制热模式")
if mode == 51:
print("空调处于送风模式")
print("空调风速为:%d"%(speed-48))
else:
mode=val[15]
temperature2=(val[16]-48)*10
temperature2=temperature2+val[17]-48
temperature2=str(temperature2)
temperature=temperature2
speed=val[18]
elif val[5]==49:
is_open=val[19]-48
elif val[6]==49:
is_insert=val[20]-48
def recvData():
global tcpClientSocket
while True:
recvData = tcpClientSocket.recv(1024)
if len(recvData) == 0:
print('服务器已关闭!')
tcpClientSocket.close()
break
print('在服务器收到消息:%s' % recvData)
run(recvData)
time.sleep(1)
# 发送数据
def sendData():
global flag
global tcpClientSocket
while True:
sendData = "0100000"+temperature+humidity+str(light1)+str(light2)+str(light3)+str(light4)+str(mode)+str(temperature2)+str(speed)+str(is_open)+str(is_insert)
while flag==1:
pass
flag=1
tcpClientSocket.send(sendData.encode())
flag=0
time.sleep(5)
def main():
global temperature
global humidity
global light1
global light2
global light3
global light4
global mode
global temperature2
global speed
global is_open
global is_insert
global tcpClientSocket
tcpClientSocket = None
temperature = "30"
humidity = "45"
light1 = "0"
light2 = "0"
light3 = "0"
light4 = "0"
mode = "0"
temperature2 = "00"
speed = "0"
is_open = "0"
is_insert = "0"
tcpClientSocket = socket(AF_INET, SOCK_STREAM)
serverIP = "localhost"
serverPort = 1234
serverAdd = (serverIP, serverPort)
tcpClientSocket.connect(serverAdd)
tr = Thread(target=recvData)
ts = Thread(target=sendData)
tr.start()
ts.start()
tr.join()
ts.join()
tcpClientSocket.close()
if __name__ == "__main__":
main()
Server.py:
# coding=utf-8
from threading import Thread
from socket import *
import time
import datetime
tcpSocket = None
aliveConnList = []
temperature="30"
humidity="45"
light1="0"
light2="0"
light3="0"
light4="0"
mode="0"
temperature2="00"
speed="0"
is_open="0"
is_insert="0"
flag=0
def update(val):
global flag
temperature=val[7:9]
humidity=val[9:11]
light1=val[11]
light2=val[12]
light3=val[13]
light4=val[14]
mode=val[15]
temperature2=val[16:18]
speed=val[18]
is_open=val[19]
is_insert=val[20]
print("当前室内温度为:%s"%(temperature))
print("当前室内湿度为:%s"%(humidity))
if light1==48:
print("1号灯未打开")
elif light1==49:
print("1号灯已被打开")
elif light1==50:
print("1号灯光开强光")
elif light1==51:
print("1号灯开最强光")
if light2==48:
print("2号灯未打开")
elif light2==49:
print("2号灯已被打开")
elif light2==50:
print("2号灯光开强光")
elif light2==51:
print("2号灯开最强光")
if light3==48:
print("3号灯未打开")
elif light3==49:
print("3号灯已被打开")
elif light3==50:
print("3号灯光开强光")
elif light3==51:
print("3号灯开最强光")
if light4==48:
print("4号灯未打开")
elif light4==49:
print("4号灯已被打开")
elif light4==50:
print("4号灯光开强光")
elif light4==51:
print("4号灯开最强光")
if mode==49:
print("空调处于制冷模式,温度为:%s,风速为:%s"%(temperature2,speed))
if mode == 50:
print("空调处于制冷模式,温度为:%s,风速为:%s"% (temperature2,speed))
if mode == 51:
print("空调处于送风模式,温度为:%s,风速为:%s"% (temperature2,speed))
if is_open==48:
print("开窗")
else:
print("关窗")
if is_insert==48:
print("还未插卡")
else:
print("已插卡")
recall = datetime.datetime.now()
msg = "accept! time:"+str(recall)
for s in aliveConnList:
newSocket = s[0]
while flag == 1:
pass
flag=1
newSocket.send(msg.encode())
flag=0
time.sleep(5)
# 接受新连接线程
def acceptConn():
global aliveConnList
global tcpSocket
while True:
newSocket, clientAddr = tcpSocket.accept()
print('%s已连接'%(str(clientAddr)))
newSocket.settimeout(1)
aliveConnList.append((newSocket, clientAddr))
def test(val):
global flag
if val[20] == 48:
for s in aliveConnList:
newSocket=s[0]
msg = "100110000000000000000"
while flag==1:
pass
flag=1
newSocket.send(msg.encode())
flag=0
# 接收新消息线程
def recvData():
global flag
global aliveConnList
while True:
# 遍历缓冲区,有数据输出并转发,没数据超时过
for s in aliveConnList:
try:
recvData = s[0].recv(1024)
if len(recvData) > 0:
print('在客户端收到消息:%s:%s' % (s[1], recvData[0:22]))
update(recvData)
#print(recvData)
if recvData[20] == 48:
msg = "100110000000000000000"
else:
recall=datetime.datetime.now()
msg="I am here "+str(recall)
for s in aliveConnList:
newSocket = s[0]
while flag==1:
pass
flag=1
newSocket.send(msg.encode())
flag=0
else:
# 客户端断开
print('%s已断开连接' % (str(s[1])))
s[0].close()
aliveConnList.remove(s)
except timeout:
# 该连接无数据
pass
time.sleep(5)
def sendData():
global flag
while True:
for s in aliveConnList:
newSocket=s[0]
chose=input()
chose=int(chose)
msg=""
if chose==1:
msg="100000100000000000001"
elif chose==2:
print("0.关闭灯")
print("1.打开灯")
print("2.灯变亮")
print("3.最大亮度")
cho=str(input())
msg="10010000000"+cho+"555000000"
elif chose==3:
print("0.关闭灯")
print("1.打开灯")
print("2.灯变亮")
print("3.最大亮度")
cho=input()
msg="100100000005"+cho+"55000000"
elif chose==4:
print("0.关闭灯")
print("1.打开灯")
print("2.灯变亮")
print("3.最大亮度")
cho=input()
msg="1001000000055"+cho+"5000000"
elif chose==5:
print("0.关闭灯")
print("1.打开灯")
print("2.灯变亮")
print("3.最大亮度")
cho=input()
msg="10010000000555"+cho+"000000"
elif chose==6:
m=str(input("请输入空调模式:"))
te=str(input("请输入空调温度:"))
sp=str(input("请输入空调风速:"))
msg="100010000000000"+m+te+sp+"00"
elif chose==7:
msg="100010000000000000000"
elif chose==8:
msg="100000100000000000000"
while flag == 1:
pass
flag=1
newSocket.send(msg.encode())
flag=0
def main():
global temperature
global humidity
global light1
global light2
global light3
global light4
global mode
global temperature2
global speed
global is_open
global is_insert
global flag
temperature = "30"
humidity = "45"
light1 = "0"
light2 = "0"
light3 = "0"
light4 = "0"
mode = "0"
temperature2 = "00"
speed = "0"
is_open = "0"
is_insert = "0"
flag=0
global tcpSocket
tcpSocket = socket(AF_INET, SOCK_STREAM)
address = ('localhost', 1234)
tcpSocket.bind(address)
tcpSocket.listen(5)
print("欢迎使用")
print("请选择要进行的操作:")
print("1.插卡取电")
print("2.管理1号灯")
print("3.管理2号灯")
print("4.管理3号灯")
print("5.管理4号灯")
print("6.管理空调")
print("7.查看空调设置")
print("8.拔卡走人")
ta = Thread(target=acceptConn)
ts = Thread(target=sendData)
tr = Thread(target=recvData)
ta.start()
tr.start()
ts.start()
ta.join()
tr.join()
ts.join()
tcpSocket.close()
if __name__ == "__main__":
main()