标签:课程设计 cout int recv 智能家居 send char 2019 buf
题目描述:
- 智能家居协议设计
实现一个基于socket的物联网服务器,接收来自客户端的数据。实现一个物联网客户端,模拟设备。客户端产生数据,发送至服务器,服务器根据协议对数据作出处理。
需要模式的设备有:
温度传感器:采集房间温度信息。
湿度传感器:采集房间湿度信息。
空调:可以根据服务器发来的指令进行调节模式(制冷、制热、送风)、设置温度、风速;还可以根据服务器的指令上传子自己的当前状态:模式、温度、风速。
门窗磁:可以根据服务器发来的指令打开或者关闭窗户。
要求:
设计通信协议完成数据的双向传输,应用层协议应包含首部和数据部分。
学校:烟台大学计算机与控制工程学院2017级
完成时间:2019.12
老师:赵老师
具体实现过程参考附带的链接资源,此处只提供源码和一些实验指导,因为已经是放寒假已经半个月了,所以博客写的有些时间久远,大部分思路是在链接资源的实验报告里面:
CSDN资源:https://download.csdn.net/my
百度云:链接:https://pan.baidu.com/s/1DBFi4i2g1lL3MoQC6MQAGA
提取码:54hx
压缩包里面还有个一复杂版本的,那是我原来从GitHub上找的demo,比较完整,而且实现一些死锁问题的解决方案。
本次实验时间还是比较长的。但是实验还是比较匆忙的完成,因为大家都是提前验收的,没有考虑一些像是死锁一样的问题。
server.cpp
#include<iostream>
#include<stdio.h>
#include<Winsock2.h>
#include<fstream>
#include<cstdio>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
char recv_buf[100];
char send_buf[100];
void print(char *s)
{
int t, p;
if(s[3] == '0'){ //温度传感器
p = 0;
t = 6;
int tem; // 温度
int start_num = s[4] - '0';
int num = s[5] - '0';
cout<<"------------------------------------"<<endl;
cout<<"收到来自"<<num<<"个温度传感器的数据:如下"<<endl;
while(num--){
tem = 0;
tem += (s[t++] - '0')*10;
tem += (s[t++] - '0');
cout<<start_num+p<<"号位置温度为:"<<tem<<"° ";
p++;
}
cout<<"\n------------------------------------"<<endl;
}
else if(s[3] == '1'){ //湿度传感器
p = 0;
t = 6;
int shidu; // 湿度
int start_num = s[4] - '0';
int num = s[5] - '0';
cout<<"收到来自"<<num<<"个湿度传感器的数据:";
while(num--){
shidu = 0;
shidu += (s[t++] - '0')*10;
shidu += (s[t++] - '0');
cout<<start_num+p<<"号位置湿度为:"<<shidu<<"% ";
p++;
}
}
cout<<endl;
return ;
}
int main()
{
WORD wsa = MAKEWORD(2,2);
WSADATA wsaData;
if(WSAStartup(wsa, &wsaData)!=0)
{
cout<<"初始化失败"<<endl; //这进行初始化
return 0;
}
//创建套接字
SOCKET s_server = socket(AF_INET, SOCK_STREAM, 0);
//AF_INET 面向网络的 IPV4
//AF_INET6用于第6版因特网协议(IPv6)寻址
//SOCK_STREAM TCP链接 面向链接 SOCK_DGRAM 无连接 UDP
if(s_server==INVALID_SOCKET) //INVALID_SOCKET是-1 错误标志
{
cout<<"socket创建失败"<<endl;
return 0;
}
//这里配置server配置信息
sockaddr_in server_addr; //创建sockaddr_in结构体
server_addr.sin_family = AF_INET; //IPV4协议
server_addr.sin_port = htons(8888); //本地端口8888
server_addr.sin_addr.S_un.S_addr = INADDR_ANY; //设置地址 监听本地端口
//利用bind函数将socket和配置信息绑定
//bind通常和下面的listen配套使用 处于被动链接中泰
if ( bind( s_server,(SOCKADDR *)&server_addr,sizeof(SOCKADDR)) ==SOCKET_ERROR )
{
//socket和配置绑定
cout<<"ERROR bind!!"<<endl; //绑定错误
WSACleanup();
}
if(listen( s_server,5 )<0)
{
cout<<"监听失败"<<endl;
}
cout<<"监听链接请求~~~"<<endl;
sockaddr_in clinet_addr; //用于获取客户端地址端口信息 用于回传
SOCKET s_accept;
//这里定义了一个用于接收的sockaddr_in名字为s_accept。用于接收客户端的地址信息和端口信息,用于回传。
int len=sizeof(SOCKADDR);
s_accept = accept(s_server,(SOCKADDR *)&clinet_addr,&len);
//在这里阻塞 挂起等待
if( s_accept ==SOCKET_ERROR ) //
{
cout<<"connect error"<<endl;
return 0;
}
cout<<"connection is OK;ready to accept"<<endl;
//两个buff缓冲区,用于缓存接收字符和发送字符。
while(1)
{
int recv_len= recv(s_accept,recv_buf,100,0);
//这里 即使链接断开 也能继续监听 服务端不关闭
if(recv_len<0)
{
cout<<"服务器继续监听~~~~"<<endl;
s_accept = accept(s_server,(SOCKADDR *)&clinet_addr,&len);
//客户端断开阻塞,挂起等待。在这里阻塞 挂起等待
continue;
if( s_accept ==SOCKET_ERROR ) //
{
cout<<"connect error"<<endl;
return 0;
}
}
char recv_message[100]; //接收到的数据帧
strcpy(recv_message,recv_buf);
int message_len = strlen(recv_message); //接收到的数据帧的长度
print(recv_message); //输出温度/湿度の状态
char solid_head[] = {"5A"}; //固定头 帧头
char function_num[] = {"0"}; //S-->C
char device_type[3]; //设备类型,0-空调,1-门窗磁
//判断空调
if(recv_message[3] == '0' || recv_message[3] == '1')
device_type[0] = '0'; // 0代表空调
device_type[1] = '\0';
char device_start[] = {"F"}; //不用 不使用
char device_num[] = {"F"}; //不用
strcat(send_buf,solid_head);
strcat(send_buf,function_num);
strcat(send_buf,device_type);
strcat(send_buf,device_start);
strcat(send_buf,device_num);
int p;
if(recv_message[3] == '0'){ //发来的是温度
cout<<"调节空调温度,发送数据帧:";
p = 6;
int temsensor_num = recv_message[5] - '0';
int temperature = 0;
while(temsensor_num--){
temperature += (recv_message[p++] - '0')*10;
temperature += (recv_message[p++] - '0');
}
temperature /= (recv_message[5] - '0'); //空调模式
if(temperature<18){
char moshi[] = {"1"}; //制热
char tem_standard[] = {"18"};
char wind_speed[] = {"1"};
strcat(send_buf,moshi);
strcat(send_buf,tem_standard);
strcat(send_buf,wind_speed);
}
else if(temperature>18){
char moshi[] = {"0"}; //制冷
char tem_standard[] = {"18"};
char wind_speed[] = {"1"};
strcat(send_buf,moshi);
strcat(send_buf,tem_standard);
strcat(send_buf,wind_speed);
}
else{
char moshi[] = {"2"}; //送风
char tem_standard[] = {"18"};
char wind_speed[] = {"0"};
strcat(send_buf,moshi);
strcat(send_buf,tem_standard);
strcat(send_buf,wind_speed);
}
}
if(recv_message[3] == '1'){ //发来的是湿度
cout<<"调节空调湿度,发送数据帧:";
p = 6;
int humsensor_num = recv_message[5] - '0';
int humperature = 0;
while(humsensor_num--){
humperature += (recv_message[p++] - '0')*10;
humperature += (recv_message[p++] - '0');
}
humperature /= (recv_message[5] - '0');
if(humperature<30){
char moshi[] = {"3"}; //提高湿度
char tem_standard[] = {"30"};
char wind_speed[] = {"1"};
strcat(send_buf,moshi);
strcat(send_buf,tem_standard);
strcat(send_buf,wind_speed);
}
else if(humperature>30){
char moshi[] = {"4"}; //降低湿度
char tem_standard[] = {"30"};
char wind_speed[] = {"1"};
strcat(send_buf,moshi);
strcat(send_buf,tem_standard);
strcat(send_buf,wind_speed);
}
else{
char moshi[] = {"2"}; //送风
char tem_standard[] = {"30"};
char wind_speed[] = {"0"};
strcat(send_buf,moshi);
strcat(send_buf,tem_standard);
strcat(send_buf,wind_speed);
}
}
//判断门窗锁
//cout<<send_buf<<endl;
send(s_accept,send_buf,100,0);
send_buf[3] = '1'; //此时设备为门窗磁
if(recv_message[3] == '0' || recv_message[3] == '1'){
cout<<"调节门窗,发送数据帧:";
p = 6;
int temsensor_num = recv_message[5] - '0';
int temperature = 0;
while(temsensor_num--){
temperature += (recv_message[p++] - '0')*10;
temperature += (recv_message[p++] - '0');
}
temperature /= (recv_message[5] - '0');
if(temperature > 18){
send_buf[6] = '0'; //门窗关闭
}
else{
send_buf[6] = '1'; //门窗打开
}
send_buf[7] = 'F';
send_buf[8] = 'F';
send_buf[9] = 'F';
}
send(s_accept,send_buf,100,0);
cout<<send_buf<<endl;
memset(send_buf,0,sizeof(send_buf));
cout<<"发送成功"<<endl<<endl;
}
closesocket(s_server);
closesocket(s_accept);
//释放DLL资源
WSACleanup();
return 0;
}
/*
5A00121723, 10
输入服务端消息
456
发送成功
5A00311723, 10
输入服务端消息
*/
client.cpp
#include<iostream>
#include<stdio.h>
#include<Winsock2.h>
#include<windows.h>
#include <ctime>
#include <cstring>
#define random(a,b) (rand()%(b-a)+a)
#pragma comment(lib, "WS2_32")
using namespace std;
char send_buf[200]; //发送数据报
char accept_buf[200]; //接受数据报
string strtem(int i); //生成随机温度数据段
string strhum(int i); //生成随机湿度数据段
void tcpxy(); //生成上传服务器报文
void analysis(char receive[]); //对服务器传回的报文进行解析
int main()
{
WORD wsa = MAKEWORD(2,2);
WSADATA wsaData;
//WSADATA结构体中主要包含了系统所支持的Winsock版本信息 WSA API
if(WSAStartup(wsa, &wsaData)!=0)
{
cout<<"初始化失败"<<endl; //这进行初始化
return 0;
}
SOCKET s_server = socket(AF_INET, SOCK_STREAM, 0);
if(s_server==INVALID_SOCKET)
{
cout<<"socket创建失败"<<endl;
return 0;
}
sockaddr_in server_addr;
server_addr.sin_family = AF_INET; //IPV4协议
server_addr.sin_port = htons(8888); //服务器端口
server_addr.sin_addr.S_un.S_addr = inet_addr("192.168.43.15"); //服务器IP
if (connect(s_server, (SOCKADDR *)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) //链接失败
{
cout << "server connnet fail!!" << endl;
WSACleanup();
return 0;
}
else
{
cout << "服务器连接成功!" << endl<<endl;
}
Sleep(1*1000);
cout<<"开始上传温度和湿度传感器信息..."<<endl<<endl;
while(1)
{
cout<<"上传服务器报文为:"<<endl;
tcpxy();
//cout<<endl;
// cin>>send_buf;//生成当前传感器状态。
//cout<<"发送的"<<endl;
int res_len = send(s_server,send_buf,100,0);
if(res_len<0)
{
cout<<"error"<<endl;
return 0;
}
cout<<"报文发送成功,等待接受"<<endl<<endl;
recv(s_server, accept_buf, 200, 0);
cout<<"收到服务器端消息";
analysis(accept_buf);
Sleep(1*1000);
cout<<endl;
recv(s_server, accept_buf, 200, 0);
cout<<"收到服务器端消息";
analysis(accept_buf);
cout<<"------------------------------------------------"<<endl<<endl<<endl;
Sleep(3*1000);//延时3秒
}
closesocket(s_server);
//释放DLL资源
WSACleanup();
return 0;
}
void analysis(char receive[]) //解析
{
cout<<"传输的报文为:"<<receive<<endl;
cout<<"报文解析结果为:"<<endl;
// for(int i=0;i<strlen(receive);i++)
// cout<<receive[i]<<" ";
// cout<<endl;
int rev_length=strlen(receive);
if(receive[2]=='1')
{
cout<<"当前室内温度为:"<<endl;
}
else if(receive[2]=='0')
{
string strp1;
string strp2;
string strp3;
string strp4;
string strp5;
if(receive[7]=='1'&&receive[8]=='8')
strp3="温度为:18%";
else if(receive[7]=='3'&&receive[8]=='0')
strp3="湿度为:30%";
//cout<<"服务器发送的指令为:"<<endl;
if(receive[3]=='0')
{
strp1="空调";
if(receive[6]=='0')
{
strp2="制冷";
}
else if(receive[6]=='1')
{
strp2="制热";
}
else if(receive[6]=='2')
{
strp2="送风";
}
else if(receive[6]=='3')
{
strp2="提湿度";
}
else if(receive[6]=='4')
{
strp2="减湿度";
}
if(receive[9]=='0')
{
strp4="慢风速";
}
else if(receive[9]=='1')
{
strp4="中风速";
}
else if(receive[9]=='2')
{
strp4="高风速";
}
cout<<endl<<strp1+"启动"+strp2+"功能,"+"目标"+strp3+","+"风速为:"+strp4<<endl;
}
else if(receive[3]=='1')
{
strp1="门窗磁";
if(receive[6]=='0')
strp5="开窗";
else if(receive[6]=='1')
{
strp5="关窗";
}
cout<<endl<<strp1+"启动"+strp5+"功能."<<endl;
}
}
}
void tcpxy()
{
memset(send_buf,0,sizeof(send_buf));
// memset(accept_buf,0,sizeof(accept_buf));
int j=0;
srand((int)time(0)); // 产生随机种子 把0换成NULL也行
int devicebnum=random(0,2); //设备类型 0 温度,1 湿度
int tempnum=random(1,5);//温度反应器数量
int humnum=random(1,5);//湿度感应器数量
int startnum=random(1,5);
int direction=1;//1表示客户端到服务器,0表示服务器到客户端
string stableheader="5A";
if(startnum==1)
{
tempnum=random(1,5);
humnum=random(1,5);
}
else if(startnum==2)
{
tempnum=random(1,5);
humnum=random(1,5);
}
else if(startnum==3)
{
tempnum=random(1,3);
humnum=random(1,3);
}
else
{
tempnum=1;
humnum=1;
}
string str3 = to_string(devicebnum);
string str4 = to_string(tempnum);
string str5 = to_string(humnum);
string str6 = to_string(startnum);
string str7 = to_string(direction);
string str=stableheader+str7+str3+str6+str4; //帧格式:帧头+发送方向+设备类型+开始编号+数量+数据段
if(devicebnum==0)
str+=strtem(tempnum);
else if(devicebnum==1)
str+=strhum(tempnum);
cout<<str<<endl;
// cout<<str.length()<<endl;
for(int i=0; i<str.length(); i++)
{
send_buf[j]=str[i];
j++;
}
char qishi=send_buf[4];
char shebinum=send_buf[5];
// if(send_buf[3]=='0')
// {
// strp1="温度传感器温度分别为:";
// }
// else if(send_buf[3]=='1')
// {
// strp1="湿度传感器湿度分别为:"
// }
// cout<<"当前房间"+strp1+
}
string strtem(int i)//生成随机温度数据段
{
int temperature;
string str;
for(int j=0; j<i; j++)
{
temperature=random(15,26);//产生随机温度。
str+=to_string(temperature);
}
return str;
}
string strhum(int i)//生成随机湿度数据段
{
int humidity;
string str;
for(int j=0; j<i; j++)
{
humidity=random(25,46);//产生随机湿度。
str+=to_string(humidity);
}
return str;
}
最重要的是感谢周学长和虎 学长o(╥﹏╥)o,原来找的那个demo太大太难了,入手慢,感谢o(╥﹏╥)o
涂山北枫 发布了39 篇原创文章 · 获赞 27 · 访问量 2万+ 私信 关注标签:课程设计,cout,int,recv,智能家居,send,char,2019,buf 来源: https://blog.csdn.net/Waybyway/article/details/104079787
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。