问题
客户端业务逻辑如何实现?
与服务设备具体交互细节如何设计?
客户端业务逻辑实现
用户输入处理
- 字符串空格处理,分割获取命令与参数
服务信息处理
- 字符串预处理,分割获取服务命令
- 存储服务命令与设备地址之间的映射(命令字符串 => 地址字符串)
客户端业务逻辑实现 - 用户输入处理
服务端逻辑实现
查询消息处理
- 接收广播,并回复UDP消息
服务命令处理
- 接收 TCP 连接,通过 请求-响应 的模式进行服务
UDP响应模块设计
服务模块设计
TCP 响应模块设计
客户端响应接收
客户端服务端交互实现
main.c
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <string.h>
-
#include <unistd.h>
-
#include <sys/socket.h>
-
#include "utility.h"
-
#include "addr_mgr.h"
-
#include "udp_point.h"
-
#include "tcp_client.h"
-
#include "type_def.h"
-
-
#define BUF_SIZE 64
-
#define DESC_SIZE 32
-
#define ADDR_SIZE 16
-
#define USAGE_SIZE 256
-
-
#define DIM(a) sizeof((a)) / sizeof((*a))
-
-
typedef
struct
-
{
-
const
char* cmd;
-
void (*handler)(
const
char*);
-
} Handler;
-
-
static int GetCharCount(const char* s, int c)
-
{
-
int ret =
0;
-
-
if(s)
-
{
-
while(*s)
-
{
-
if(*s == c)
-
{
-
ret++;
-
}
-
-
s++;
-
}
-
}
-
-
return ret;
-
}
-
-
static void ParseCommand(const char* s)
-
{
-
const
char* desc = s;
-
const
char* addr = desc + DESC_SIZE;
-
const
char* usage = addr + ADDR_SIZE;
-
int count =
0;
-
int cnt =
0;
-
char** arg =
NULL;
-
char** cmd =
NULL;
-
int r =
0;
-
-
printf(
"desc: %s\n", desc);
-
printf(
"addr: %s\n", addr);
-
-
count =
GetCharCount(usage,
'\n');
-
arg =
Malloc2d(
char, count, BUF_SIZE);
-
-
if(arg && (count >
0))
-
{
-
r =
DivideByChar(usage,
'\n', arg, count, BUF_SIZE);
-
-
for(
int i =
0; i < r; i++)
-
{
-
count =
GetCharCount(arg[i],
' ') +
1;
-
cmd =
Malloc2d(
char, count, BUF_SIZE);
-
-
if(cmd && (count >
0))
-
{
-
cnt =
DivideByChar(arg[i],
' ', cmd, count, BUF_SIZE);
-
-
for(
int j =
1; j < cnt; j++)
-
{
-
AddrMgr_Add(cmd[j], addr);
-
printf(
"%s %s\n", cmd[j], addr);
-
}
-
}
-
-
Free2d(cmd);
-
}
-
}
-
-
Free2d(arg);
-
}
-
-
void Query_Handler(const char* s)
-
{
-
UdpPoint* point =
UdpPoint_New(
8888);
-
Message* msg =
NULL;
-
int brd =
1;
-
char* remote =
"255.255.255.255";
-
int port =
9999;
-
int i =
0;
-
-
if(point)
-
{
-
UdpPoint_SetOpt(point, SOL_SOCKET, SO_BROADCAST, &brd,
sizeof(brd));
-
msg =
Message_New(TYPE_QUERY,
0,
0,
0,
NULL,
0);
-
-
if(msg)
-
{
-
UdpPoint_SendMsg(point, msg, remote, port);
-
-
free(msg);
-
msg =
NULL;
-
}
-
-
while(i <
3)
-
{
-
if(
UdpPoint_Available(point) >
0)
-
{
-
msg =
UdpPoint_RecvMsg(point,
NULL,
NULL);
-
-
if(msg)
-
{
-
if(msg->type == TYPE_RESPONSE)
-
{
-
printf(
"Find service!\n");
-
-
ParseCommand(msg->payload);
-
-
i =
0;
-
free(msg);
-
msg =
NULL;
-
}
-
else
if(msg->type == TYPE_ERROR)
-
{
-
printf(
"Can NOT find service!\n");
-
}
-
}
-
-
}
-
else
-
{
-
sleep(
1);
-
i++;
-
}
-
}
-
}
-
-
UdpPoint_Del(point);
-
}
-
-
void Touch_Handler(const char* s)
-
{
-
if(s && *s)
-
{
-
TcpClient* client =
TcpClient_New();
-
char* addr =
AddrMgr_Find(s);
-
Message* msg =
NULL;
-
-
if(client && addr &&
TcpClient_Connect(client, addr,
8888))
-
{
-
msg =
Message_New(TYPE_TOUCH,
0,
0,
0, s,
strlen(s) +
1);
-
-
if(msg)
-
{
-
TcpClient_SendMsg(client, msg);
-
-
free(msg);
-
msg =
NULL;
-
-
msg =
TcpClient_RecvMsg(client);
-
-
if(msg && (msg->type == TYPE_RESPONSE))
-
{
-
printf(
"%s\n", msg->payload);
-
free(msg);
-
msg =
NULL;
-
}
-
}
-
}
-
-
TcpClient_Del(client);
-
}
-
}
-
-
Handler g_handler[] = {
-
{
"query", Query_Handler},
-
{
"touch", Touch_Handler},
-
};
-
-
int main(void)
-
{
-
char line[BUF_SIZE] = {
0};
-
char** arg =
NULL;
-
int r =
0;
-
-
printf(
"<<<< This is client demo >>>>\n");
-
-
arg =
Malloc2d(
char,
2, BUF_SIZE);
-
-
while(arg)
-
{
-
fgets(line,
sizeof(line), stdin);
-
line[
strlen(line) -
1] =
0;
-
-
if(*line)
-
{
-
r =
DivideByChar(line,
' ', arg,
2, BUF_SIZE);
-
-
for(
int i =
0; (i <
DIM(g_handler) && (r >
0)); i++)
-
{
-
if(
strcmp(arg[
0], g_handler[i].cmd) ==
0)
-
{
-
g_handler[i].
handler(arg[
1]);
-
break;
-
}
-
}
-
}
-
}
-
-
Free2d(arg);
-
-
return
0;
-
}
response_task.c
-
#include <stdio.h>
-
#include "response_task.h"
-
#include "udp_point.h"
-
#include "type_def.h"
-
-
#define DESC_SIZE 32
-
#define ADDR_SIZE 16
-
#define USAGE_SIZE 256
-
-
void* Response_Task(const char* arg)
-
{
-
UdpPoint* point =
NULL;
-
Message* msg =
NULL;
-
char remote[
16] = {
0};
-
int port =
0;
-
-
point =
UdpPoint_New(
9999);
-
-
if(point)
-
{
-
printf(
"point = 0x%X\n", point);
-
-
while(
1)
-
{
-
msg =
UdpPoint_RecvMsg(point, remote, &port);
-
-
if(msg && msg->type == TYPE_QUERY)
-
{
-
free(msg);
-
msg =
NULL;
-
-
msg =
Message_New(TYPE_RESPONSE,
0,
0,
0,
NULL, DESC_SIZE + ADDR_SIZE + USAGE_SIZE);
-
-
if(msg)
-
{
-
strncpy(msg->payload,
Service_GetDesc(), DESC_SIZE);
-
strncpy(msg->payload + DESC_SIZE,
Wifi_IpAddr(), ADDR_SIZE);
-
strncpy(msg->payload + DESC_SIZE + ADDR_SIZE,
Service_GetUsage(), USAGE_SIZE);
-
-
UdpPoint_SendMsg(point, msg, remote, port);
-
-
free(msg);
-
msg =
NULL;
-
}
-
else
-
{
-
Message m = {TYPE_ERROR};
-
-
UdpPoint_SendMsg(point, &m, remote, port);
-
}
-
-
}
-
else
-
{
-
Message m = {TYPE_ERROR};
-
-
UdpPoint_SendMsg(point, &m, remote, port);
-
}
-
}
-
-
UdpPoint_Del(point);
-
}
-
-
return
NULL;
-
}
local_service.h
-
#ifndef LOCAL_SERVICE_H
-
#define LOCAL_SERVICE_H
-
-
typedef
struct
-
{
-
float illumination;
-
float humidity;
-
float temperature;
-
int light;
-
} SvrData;
-
-
void Service_Init(void);
-
const char* Service_GetDesc(void);
-
const char* Service_GetUsage(void);
-
SvrData Service_GetData(void);
-
int Service_SetLight(int on);
-
-
#endif
local_service.c
-
#include "local_service.h"
-
-
void Service_Init(void)
-
{
-
-
}
-
-
const char* Service_GetDesc(void)
-
{
-
return
"Environment Service";
-
}
-
-
const char* Service_GetUsage(void)
-
{
-
return
"Illumination: Ill_Get\n"
-
"Temperature: Tem_Get\n"
-
"Humidity: Hum_Get\n"
-
"Light: Lig_Get Lig_Set_On Lig_Set_Off\n";
-
}
-
-
SvrData Service_GetData(void)
-
{
-
SvrData ret = {
188,
0.33,
35.6,
1};
-
-
return ret;
-
}
-
-
int Service_SetLight(int on)
-
{
-
int ret =
1;
-
-
printf(
"set light: %d\n", on);
-
-
return ret;
-
}
service_task.c
-
#include <stdio.h>
-
#include "stdlib.h"
-
#include <string.h>
-
#include "service_task.h"
-
#include "tcp_client.h"
-
#include "tcp_server.h"
-
#include "local_service.h"
-
#include "type_def.h"
-
-
typedef
struct
-
{
-
const
char* cmd;
-
void* data;
-
char* (*handler)(
void*);
-
} Handler;
-
-
static char* FormatNumber(float num)
-
{
-
char* ret = (
char*)
malloc(
16);
-
-
snprintf(ret,
16,
"%.2f", num);
-
-
return ret;
-
}
-
-
static char* Ill_Get_Handler(void* data)
-
{
-
return
FormatNumber(
Service_GetData().illumination);
-
}
-
-
static char* Tem_Get_Handler(void* data)
-
{
-
return
FormatNumber(
Service_GetData().temperature);
-
}
-
-
static char* Hum_Get_Handler(void* data)
-
{
-
return
FormatNumber(
Service_GetData().humidity);
-
}
-
-
static char* Lig_Get_Handler(void* data)
-
{
-
char* ret = (
char*)
malloc(
4);
-
-
if(
Service_GetData().light)
-
{
-
strcpy(ret,
"on");
-
}
-
else
-
{
-
strcpy(ret,
"off");
-
}
-
-
return ret;
-
}
-
-
static char* Lig_Set_Handler(void* data)
-
{
-
char* ret = (
char*)
malloc(
4);
-
-
Service_SetLight((
int)data);
-
-
if(data)
-
{
-
strcpy(ret,
"on");
-
}
-
else
-
{
-
strcpy(ret,
"off");
-
}
-
-
return ret;
-
}
-
-
static Handler g_handler[] =
-
{
-
{
"Ill_Get",
NULL, Ill_Get_Handler},
-
{
"Tem_Get",
NULL, Tem_Get_Handler},
-
{
"Hum_Get",
NULL, Hum_Get_Handler},
-
{
"Lig_Get",
NULL, Lig_Get_Handler},
-
{
"Lig_Set_On", (
void*)
1, Lig_Set_Handler},
-
{
"Lig_Set_Off", (
void*)
0, Lig_Set_Handler},
-
};
-
-
static
int g_handler_size =
sizeof(g_handler) /
sizeof(*g_handler);
-
-
static void Server_Listener_Handler(TcpClient* client, int evt)
-
{
-
if(evt == EVT_COON)
-
{
-
printf(
"a client connect\n");
-
}
-
else
if(evt == EVT_DATA)
-
{
-
Message* msg =
NULL;
-
char* s =
NULL;
-
-
msg =
TcpClient_RecvMsg(client);
-
-
if(msg && (msg->type == TYPE_TOUCH))
-
{
-
printf(
"service type = %s\n", msg->payload);
-
-
for(
int i =
0; i < g_handler_size; i++)
-
{
-
if(
strcmp(msg->payload, g_handler[i].cmd) ==
0)
-
{
-
s = g_handler[i].
handler(g_handler[i].data);
-
-
break;
-
}
-
}
-
-
free(msg);
-
msg =
NULL;
-
-
if(s)
-
{
-
msg =
Message_New(TYPE_RESPONSE,
0,
0,
0, s,
strlen(s) +
1);
-
free(s);
-
-
if(msg)
-
{
-
TcpClient_SendMsg(client, msg);
-
free(msg);
-
}
-
else
-
{
-
Message m = {TYPE_ERROR};
-
-
TcpClient_SendMsg(client, &m);
-
}
-
-
free(s);
-
}
-
}
-
else
-
{
-
const
char* message =
"Invalid touch request";
-
-
free(msg);
-
-
msg =
Message_New(TYPE_RESPONSE,
0,
0,
0, message,
strlen(message) +
1);
-
TcpClient_SendMsg(client, &m);
-
}
-
}
-
else
if(evt == EVT_CLOSE)
-
{
-
printf(
"a client left\n");
-
}
-
-
return
NULL;
-
}
-
-
void* Service_Task(const char* arg)
-
{
-
TcpServer* server =
NULL;
-
-
server =
TcpServer_New();
-
-
if(server)
-
{
-
printf(
"server = 0x%X\n", server);
-
-
Service_Init();
-
TcpServer_SetListener(server, Server_Listener_Handler);
-
TcpServer_Start(server,
8888,
5);
-
TcpServer_DoWork(server);
-
-
TcpServer_Del(server);
-
}
-
-
return
NULL;
-
}
实验结果如下图所示
课后思考
服务模块如何获取真实环境信息?
转载:https://blog.csdn.net/qq_52484093/article/details/128429161
查看评论