https://www.cnblogs.com/yangfengwu/p/11427504.html

SmartConfig/Airkiss 配网需要APP/微信公众号,这节大家先使用我做好的APP/微信公众号

APP下载:

https://www.cnblogs.com/yangfengwu/p/11249674.html

微信公众号: 扫描这个二维码关注我的公众号

    

其余的步骤等写完8266的配网程序,在下面演示.

如果想自己实现微信绑定可以看↓ (注:配置过程和源码全部是公开的,大家看文章即可实现)

如果你已经有做网页的经验了,可以直接

如果你没有做过网页,你需要先看

  

然后需要把微信小程序篇的所有章节从头到尾看一遍

现在开始写WIFI的配网程序

其实官方给了例子

咱把例子写个单独的.C和.H文件,方便咱后期使用

smart_config.c

#include "esp_common.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "espressif/espconn.h"
#include "espressif/airkiss.h" #define server_ip "192.168.101.142"
#define server_port 9669 #define DEVICE_TYPE "gh_9e2cff3dfa51" //wechat public number
#define DEVICE_ID "122475" //model ID #define DEFAULT_LAN_PORT 12476 LOCAL esp_udp ssdp_udp;
LOCAL struct espconn pssdpudpconn;
LOCAL os_timer_t ssdp_time_serv; uint8 lan_buf[];
uint16 lan_buf_len;
uint8 udp_sent_cnt = ; const airkiss_config_t akconf =
{
(airkiss_memset_fn)&memset,
(airkiss_memcpy_fn)&memcpy,
(airkiss_memcmp_fn)&memcmp,
,
}; LOCAL void ICACHE_FLASH_ATTR
airkiss_wifilan_time_callback(void)
{
uint16 i;
airkiss_lan_ret_t ret; if ((udp_sent_cnt++) >) {
udp_sent_cnt = ;
os_timer_disarm(&ssdp_time_serv);//s
//return;
} ssdp_udp.remote_port = DEFAULT_LAN_PORT;
ssdp_udp.remote_ip[] = ;
ssdp_udp.remote_ip[] = ;
ssdp_udp.remote_ip[] = ;
ssdp_udp.remote_ip[] = ;
lan_buf_len = sizeof(lan_buf);
ret = airkiss_lan_pack(AIRKISS_LAN_SSDP_NOTIFY_CMD,
DEVICE_TYPE, DEVICE_ID, , , lan_buf, &lan_buf_len, &akconf);
if (ret != AIRKISS_LAN_PAKE_READY) {
os_printf("Pack lan packet error!");
return;
} ret = espconn_sendto(&pssdpudpconn, lan_buf, lan_buf_len);
if (ret != ) {
os_printf("UDP send error!");
}
os_printf("Finish send notify!\n");
} LOCAL void ICACHE_FLASH_ATTR
airkiss_wifilan_recv_callbk(void *arg, char *pdata, unsigned short len)
{
uint16 i;
remot_info* pcon_info = NULL; airkiss_lan_ret_t ret = airkiss_lan_recv(pdata, len, &akconf);
airkiss_lan_ret_t packret; switch (ret){
case AIRKISS_LAN_SSDP_REQ:
espconn_get_connection_info(&pssdpudpconn, &pcon_info, );
os_printf("remote ip: %d.%d.%d.%d \r\n",pcon_info->remote_ip[],pcon_info->remote_ip[],
pcon_info->remote_ip[],pcon_info->remote_ip[]);
os_printf("remote port: %d \r\n",pcon_info->remote_port); pssdpudpconn.proto.udp->remote_port = pcon_info->remote_port;
memcpy(pssdpudpconn.proto.udp->remote_ip,pcon_info->remote_ip,);
ssdp_udp.remote_port = DEFAULT_LAN_PORT; lan_buf_len = sizeof(lan_buf);
packret = airkiss_lan_pack(AIRKISS_LAN_SSDP_RESP_CMD,
DEVICE_TYPE, DEVICE_ID, , , lan_buf, &lan_buf_len, &akconf); if (packret != AIRKISS_LAN_PAKE_READY) {
os_printf("Pack lan packet error!");
return;
} os_printf("\r\n\r\n");
for (i=; i<lan_buf_len; i++)
os_printf("%c",lan_buf[i]);
os_printf("\r\n\r\n"); packret = espconn_sendto(&pssdpudpconn, lan_buf, lan_buf_len);
if (packret != ) {
os_printf("LAN UDP Send err!");
} break;
default:
os_printf("Pack is not ssdq req!%d\r\n",ret);
break;
}
} void ICACHE_FLASH_ATTR
airkiss_start_discover(void)
{
ssdp_udp.local_port = DEFAULT_LAN_PORT;
pssdpudpconn.type = ESPCONN_UDP;
pssdpudpconn.proto.udp = &(ssdp_udp);
espconn_regist_recvcb(&pssdpudpconn, airkiss_wifilan_recv_callbk);
espconn_create(&pssdpudpconn); os_timer_disarm(&ssdp_time_serv);
os_timer_setfn(&ssdp_time_serv, (os_timer_func_t *)airkiss_wifilan_time_callback, NULL);
os_timer_arm(&ssdp_time_serv, , );//1s
} void ICACHE_FLASH_ATTR
smartconfig_done(sc_status status, void *pdata)
{
switch(status) {
case SC_STATUS_WAIT:
printf("SC_STATUS_WAIT\n");
break;
case SC_STATUS_FIND_CHANNEL:
printf("SC_STATUS_FIND_CHANNEL\n");
break;
case SC_STATUS_GETTING_SSID_PSWD:
printf("SC_STATUS_GETTING_SSID_PSWD\n");
sc_type *type = pdata;
if (*type == SC_TYPE_ESPTOUCH) {
printf("SC_TYPE:SC_TYPE_ESPTOUCH\n");
} else {
printf("SC_TYPE:SC_TYPE_AIRKISS\n");
}
break;
case SC_STATUS_LINK:
printf("SC_STATUS_LINK\n");
struct station_config *sta_conf = pdata; wifi_station_set_config(sta_conf);
wifi_station_disconnect();
wifi_station_connect();
break;
case SC_STATUS_LINK_OVER:
printf("SC_STATUS_LINK_OVER\n");
if (pdata != NULL) {
//SC_TYPE_ESPTOUCH
uint8 phone_ip[] = {}; memcpy(phone_ip, (uint8*)pdata, );
printf("Phone ip: %d.%d.%d.%d\n",phone_ip[],phone_ip[],phone_ip[],phone_ip[]);
} else {
//SC_TYPE_AIRKISS - support airkiss v2.0
airkiss_start_discover();
}
smartconfig_stop();
break;
}
} void ICACHE_FLASH_ATTR
smartconfig_task(void *pvParameters)
{
smartconfig_start(smartconfig_done);
vTaskDelete(NULL);
}

smart_config.h

#ifndef APP_INCLUDE_SMART_CONFIG_H_
#define APP_INCLUDE_SMART_CONFIG_H_ void smartconfig_task(void *pvParameters); #endif /* APP_INCLUDE_SMART_CONFIG_H_ */

然后主函数

    wifi_station_disconnect();

    wifi_set_event_handler_cb(wifi_event_monitor_handle_event_cb);

    wifi_set_opmode(STATION_MODE);
smartconfig_set_type(SC_TYPE_ESPTOUCH_AIRKISS);//SmartConfig + AirKiss
xTaskCreate(smartconfig_task, "smartconfig_task", , NULL, , NULL);

现在是模块一启动就进去配网...

编译出错

加上    -lairkiss\

下载进去,咱先测试下

SmartConfig:

  

下载完WIFI的程序,复位下WIFI

     

这个APP是我做的一个面向开发使用的,该APP源码获取方式:  https://www.cnblogs.com/yangfengwu/p/11249674.html

AirKiss :  关注我的这个测试用的公众号

复位WIFI模块

    

好,现在优化下

按下固件按钮(GPIO0)大约3S, 让GPIO2那个灯快闪,进入配网模式,然后60S超时检测.还有就是不让WIFI打印官方内部写的东西(打印的东西太多了...)

#include "esp_common.h"
#include "gpio.h"
#include "uart.h"
#include "esp_timer.h"
#include "hw_timer.h"
#include "pwm.h"
#include "data_dispose.h"
#include "espconn.h"
#include "esp_wifi.h"
#include "lwip/api.h" #include "crc.h"
#include "smart_config.h" LOCAL os_timer_t public_timer;//定时器
u32 public_timer_cnt=;//累加
u32 public_timer_state=;//状态
u32 public_timer_out=;//超时
u32 public_timer_cnt1=;//累加 extern u8 Usart1ReadBuff[Usart1ReadLen];//接收数据的数组
extern u32 Usart1ReadCnt;//串口1接收到的数据个数
extern u32 Usart1ReadCntCopy;//串口1接收到的数据个数拷贝
extern u8 Usart1ReadFlage;//串口1接收到一条完整数据 #define SSID "Learn8266" //无线名称
#define PWD "11223344" //密码
struct softap_config soft_ap_Config;//AP模式配置 ResolveData ResolveDataTest;//解析数据IEEE754
//uint32 pin_info_list[1][3]={PERIPHS_IO_MUX_GPIO5_U,FUNC_GPIO5,5};//配置GPIO5作为PWM输出
//int duty[1]={0};//高电平时间是0us /******************************************************************************
* FunctionName : user_rf_cal_sector_set
* Description : SDK just reversed 4 sectors, used for rf init data and paramters.
* We add this function to force users to set rf cal sector, since
* we don't know which sector is free in user's application.
* sector map for last several sectors : ABCCC
* A : rf cal
* B : rf init data
* C : sdk parameters
* Parameters : none
* Returns : rf cal sector
*******************************************************************************/
uint32 user_rf_cal_sector_set(void)
{
flash_size_map size_map = system_get_flash_size_map();
uint32 rf_cal_sec = ; switch (size_map) {
case FLASH_SIZE_4M_MAP_256_256:
rf_cal_sec = - ;
break; case FLASH_SIZE_8M_MAP_512_512:
rf_cal_sec = - ;
break; case FLASH_SIZE_16M_MAP_512_512:
case FLASH_SIZE_16M_MAP_1024_1024:
rf_cal_sec = - ;
break; case FLASH_SIZE_32M_MAP_512_512:
case FLASH_SIZE_32M_MAP_1024_1024:
rf_cal_sec = - ;
break; default:
rf_cal_sec = ;
break;
} return rf_cal_sec;
} //串口调用此函数就说明接收到了一条完整的数据,就可以去处理了
void UartReadCallback()//定义一个函数
{ } static void wifi_event_monitor_handle_event_cb(System_Event_t *evt)
{
switch (evt->event_id)
{
case EVENT_STAMODE_CONNECTED://连接上路由器
printf("\n\tSTAMODE_CONNECTED\n"); printf("\tConnected to SSID %s, Channel %d\n",
evt->event_info.connected.ssid,
evt->event_info.connected.channel);
break; case EVENT_STAMODE_DISCONNECTED://和路由器断开
printf("\n\tSTAMODE_DISCONNECTED\n"); printf("\tDisconnect from SSID %s, reason %d\n",
evt->event_info.disconnected.ssid,
evt->event_info.disconnected.reason);
break; case EVENT_STAMODE_AUTHMODE_CHANGE://这个是 啥..
printf("\n\tSTAMODE_AUTHMODE_CHANGE\n"); printf("\tAuthmode: %u -> %u\n",
evt->event_info.auth_change.old_mode,
evt->event_info.auth_change.new_mode);
break; case EVENT_STAMODE_GOT_IP://连接上路由器,并获取了IP
printf("\n\tGOT_IP\n"); printf("\tIP:" IPSTR ",Mask:" IPSTR ",GW:" IPSTR "\n",
IP2STR(&evt->event_info.got_ip.ip),
IP2STR(&evt->event_info.got_ip.mask),
IP2STR(&evt->event_info.got_ip.gw));
break; case EVENT_STAMODE_DHCP_TIMEOUT://连接上路由器,但是路由器给WIFI模块分配IP等信息超时了
printf("\n\tSTAMODE_DHCP_TIMEOUT\n");
break; case EVENT_SOFTAPMODE_STACONNECTED://AP模式下,有设备连接WIFI模块的无线
printf("\n\tSOFTAPMODE_STACONNECTED\n"); printf("\tStation: " MACSTR "join, AID = %d\n",
MAC2STR(evt->event_info.sta_connected.mac),
evt->event_info.sta_connected.aid);
break; case EVENT_SOFTAPMODE_STADISCONNECTED://AP模式下,有设备断开和WIFI模块的无线连接
printf("\n\tSOFTAPMODE_STADISCONNECTED\n"); printf("\tstation: " MACSTR "leave, AID = %d\n",
MAC2STR(evt->event_info.sta_disconnected.mac),
evt->event_info.sta_disconnected.aid);
break; case EVENT_SOFTAPMODE_PROBEREQRECVED://这是啥??,,,信号强度改变了
printf("\n\tSOFTAPMODE_PROBEREQRECVED\n"); printf("Station PROBEREQ: " MACSTR " RSSI = %d\n",
MAC2STR(evt->event_info.ap_probereqrecved.mac),
evt->event_info.ap_probereqrecved.rssi);
break; default://其它错误
printf("\n\tswitch/case default\n");
break;
}
} //所有需要定时操作的函数在此函数中执行
LOCAL void ICACHE_FLASH_ATTR
public_timer_callback(void)
{
if(GPIO_INPUT_GET() == )//按键按下
{
public_timer_cnt++;
if(public_timer_cnt>= && public_timer_state==)//3S
{
printf("\nstartsmart\n");
public_timer_state=;
wifi_station_disconnect();
wifi_set_opmode(STATION_MODE);
smartconfig_set_type(SC_TYPE_ESPTOUCH_AIRKISS);//SmartConfig + AirKiss
xTaskCreate(smartconfig_task, "smartconfig_task", , NULL, , NULL);
}
}
else
{
if(public_timer_state!= && public_timer_cnt> && public_timer_cnt<)//短按复位
{
printf("\nsystem_restart\n");
system_restart();//复位
}
public_timer_cnt=;
} switch(public_timer_state)
{
case :break;
case :
public_timer_out++;
public_timer_cnt1++;
if(public_timer_out>=)//60S配网超时
{
printf("\nsmartconfig_timeout\n");
system_restart();//复位
}
if(public_timer_cnt1>)//LED快闪
{
public_timer_cnt1=;
GPIO_OUTPUT_SET(, -GPIO_INPUT_GET());//LED快闪
}
break;
default:break;
}
} /******************************************************************************
* FunctionName : user_init
* Description : entry of user application, init user function here
* Parameters : none
* Returns : none
*******************************************************************************/
void user_init(void)
{
GPIO_OUTPUT_SET(, );
GPIO_OUTPUT_SET(, );
GPIO_OUTPUT_SET(, );
uart_init_new();
printf("SDK version:%s\n", system_get_sdk_version()); wifi_set_opmode(STATIONAP_MODE);//配置WiFi的模式STATION + AP AP--连接WIFI自身的无线实现通信 STATION--wifi连接路由器,手机或者电脑也连接路由器,实现通信
soft_ap_Config.ssid_len = strlen(SSID);//热点名称长度,与你实际的名称长度一致就好
memcpy(soft_ap_Config.ssid,SSID,soft_ap_Config.ssid_len);//实际热点名称设置,可以根据你的需要来
memcpy(soft_ap_Config.password,PWD,strlen(PWD));//热点密码设置
soft_ap_Config.authmode = AUTH_WPA2_PSK;//加密模式
soft_ap_Config.channel = ;//信道,共支持1~13个信道
soft_ap_Config.max_connection = ;//最大连接数量,最大支持四个,默认四个 wifi_softap_set_config_current(&soft_ap_Config);//设置 Wi-Fi SoftAP 接口配置,不保存到 Flash
// wifi_softap_set_config(&soft_ap_Config);//设置 Wi-Fi SoftAP 接口配置,保存到 Flash
UartCallbackRegister(UartReadCallback);//把 UartReadCallback 函数地址传过去,在串口里面调用 os_timer_disarm(&public_timer);
os_timer_setfn(&public_timer, (os_timer_func_t *)public_timer_callback, NULL);
os_timer_arm(&public_timer, , );//10ms wifi_set_event_handler_cb(wifi_event_monitor_handle_event_cb);
}

然后还有两个地方,无论是SmartConfig 还是 Airkiss 配网,配完网以后都重启下

好,测试

按下大约3S,指示灯快闪

软件就不截图了,按照上面的步骤操作

SmartConfig 打印的信息

Airkiss 打印的信息

startsmart                ------------------------------------------
state: -> ()
rm
bcn
del if1
mode : sta(:c6:3a:d6::) STAMODE_DISCONNECTED
Disconnect from SSID qqqqq, reason
SC version: V2.5.4
scandone
scandone
SC_STATUS_FIND_CHANNEL
TYPE: AIRKISS
T|AP MAC: 9e
SC_STATUS_GETTING_SSID_PSWD
SC_TYPE:SC_TYPE_AIRKISS ------------------------------------------------------
T|pswd :
T|ssid : qqqqq
SC_STATUS_LINK
scandone
state: -> (b0)
state: -> ()
state: -> ()
add
aid
pm open phy_2,type:
cnt connected with qqqqq, channel
dhcp client start... STAMODE_CONNECTED
Connected to SSID qqqqq, Channel
ip:192.168.0.100,mask:255.255.255.0,gw:192.168.0.1 GOT_IP
IP:192.168.0.100,Mask:255.255.255.0,GW:192.168.0.1
SC_STATUS_LINK_OVER
Finish send notify! ets Jan ,rst cause:, boot mode:(,) 配网以后重启 load 0x40100000, len , room
tail
chksum 0xe5
load 0x3ffe8000, len , room
tail
chksum 0x84
load 0x3ffe8310, len , room
tail
chksum 0xd8
csum 0xd8 2nd boot version : 1.6
SPI Speed : 40MHz
SPI Mode : DIO
SPI Flash Size & Map: 32Mbit(512KB+512KB)
jump to run user1 @ ?;?榗専銓#l腸{|$#溿?b|?鞄囙c潴o飥ng?宭'?弻d寧l$屇d屼?$ ?n?倪銊cdd噞p劅銓bl刢?$s$勩?僩鋼{凔'|?ll$l`?;n?哙噑og済?鋭湝滀青?cc'o?c|?;so搇膁`c們g???sr'n躱?鋵湝??#bgo?#靸;so??l?'???{soo躱?鋵溰?c#gn?#|?;{g搇膁`肧DK version:1.5.0-dev(950076a)
mode : sta(:c6:3a:d6::) + softAP(6a:c6:3a:d6::)
add if0
dhcp server start:(ip:192.168.4.1,mask:255.255.255.0,gw:192.168.4.1)
add if1
bcn
scandone
state: -> (b0)
state: -> ()
state: -> ()
add
aid
cnt connected with qqqqq, channel 11 自动连接路由器
dhcp client start... STAMODE_CONNECTED
Connected to SSID qqqqq, Channel
ip:192.168.0.100,mask:255.255.255.0,gw:192.168.0.1 GOT_IP
IP:192.168.0.100,Mask:255.255.255.0,GW:192.168.0.1

好现在,不让调试信息通过usart0打印

这个设置以后  printf就不会通过uart0打印了 ,会用uart1(GPIO2) 打印......

这个不强求哈!!!大家不修改也可以,我只是不希望让系统一直打印各种信息,我担心后面和单片机做通信的时候会出问题!

当然大家也可以直接用  USART_SendData(uint8 uart, uint8 TxChar)  发送数据,我只不过是封装成可以用printf形式

还记得咱前面的某一节咱自己写的printf不,不过呢,咱直接用lua源码里面写的,因为我写的那个太占内存.....

把这部分代码放到 uart.c 里面

static void kprintn (void (*)(const char), uint32_t, int, int, char);
static void kdoprnt (void (*)(const char), const char *, va_list); void dbg_printf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
kdoprnt(uart0_write_char, fmt, ap);
va_end(ap);
} void dbg_vprintf(const char *fmt, va_list ap)
{
kdoprnt(uart0_write_char, fmt, ap);
} void kdoprnt(void (*put)(const char), const char *fmt, va_list ap)
{
register char *p;
register int ch, n;
unsigned long ul;
int lflag, set;
char zwidth;
char width; for (;;)
{
while ((ch = *fmt++) != '%')
{
if (ch == '\0')
return;
put(ch);
}
lflag = ;
width = ;
zwidth = ' '; reswitch:
switch (ch = *fmt++)
{
case '\0':
/* XXX print the last format character? */
return;
case 'l':
lflag = ;
goto reswitch;
case 'c':
ch = va_arg(ap, int);
put(ch & 0x7f);
break;
case 's':
p = va_arg(ap, char *);
if (p == ) {
p = "<null>";
}
while ((ch = *p++))
put(ch);
break;
case 'd':
ul = lflag ? va_arg(ap, long) : va_arg(ap, int);
if ((long)ul < ) {
put('-');
ul = -(long)ul;
}
kprintn(put, ul, , width, zwidth);
break;
case 'o':
ul = lflag ?
va_arg(ap, uint32_t) : va_arg(ap, uint32_t);
kprintn(put, ul, , width, zwidth);
break;
case 'u':
ul = lflag ?
va_arg(ap, uint32_t) : va_arg(ap, uint32_t);
kprintn(put, ul, , width, zwidth);
break;
case 'x':
ul = lflag ?
va_arg(ap, uint32_t) : va_arg(ap, uint32_t);
kprintn(put, ul, , width, zwidth);
break;
default:
if (ch >= '' && ch <= '')
{
if (ch == '' && width == && zwidth == ' ')
{
zwidth = '';
}
else
{
width = width * + ch - '';
}
goto reswitch;
}
put('%');
if (lflag)
put('l');
put(ch);
}
}
va_end(ap);
} static void kprintn(void (*put)(const char), uint32_t ul, int base, int width, char padchar)
{
/* hold a long in base 8 */
char *p, buf[(sizeof(long) * / ) + ]; p = buf;
do {
*p++ = "0123456789abcdef"[ul % base];
} while (ul /= base); while (p - buf < width--) {
put(padchar);
} do {
put(*--p);
} while (p > buf);
}

需要修改一个地方

然后全部替换为

就可以实现printf的方式了

如果大家嫌麻烦也可以不用复制粘贴那部分

直接用  uart0_write_char()

现在只是模块一开始启动的时候打印些自身的信息,后期的都是打印的咱自己写的

如果大家不希望打印信号强度

可以

好了,又完成一节

https://www.cnblogs.com/yangfengwu/p/11432795.html

26-ESP8266 SDK开发基础入门篇--编写WIFI模块 SmartConfig/Airkiss 一键配网的更多相关文章

  1. 28-ESP8266 SDK开发基础入门篇--编写wifi模块TCP 客户端程序(官方API版,非RTOS版)

    https://www.cnblogs.com/yangfengwu/p/11432795.html 注:这节实现的功能是WIFI模块作为TCP 客户端,连接咱的TCP服务器,然后实现透传 本来想着做 ...

  2. 25-ESP8266 SDK开发基础入门篇--控制WIFI连接路由器

    https://www.cnblogs.com/yangfengwu/p/11324411.html 说个事情,现在SDK的版本已经出到3.0了,但是我还是使用2.0 如果只是为了学习研究   选择3 ...

  3. 29-ESP8266 SDK开发基础入门篇--编写TCP 客户端程序(Lwip RAW模式,非RTOS版,精简入门)

    https://www.cnblogs.com/yangfengwu/p/11456667.html 由于上一节的源码长时间以后会自动断开,所以再做这一版非RTOS版的,咱直接用lua源码里面别人写的 ...

  4. 8-ESP8266 SDK开发基础入门篇--编写串口上位机软件

    https://www.cnblogs.com/yangfengwu/p/11087558.html 咱用这个编写 ,版本都无所谓哈,只要自己有就可以,不同版本怎么打开 https://www.cnb ...

  5. 27-ESP8266 SDK开发基础入门篇--编写Android SmartConfig一键配网程序

    style="font-size: 18pt;">https://www.cnblogs.com/yangfengwu/p/11429007.html https://wik ...

  6. 22-ESP8266 SDK开发基础入门篇--编写Android TCP客户端 , 连接和断开

    https://www.cnblogs.com/yangfengwu/p/11192618.html 有些很细致的东西参考这篇   https://www.cnblogs.com/yangfengwu ...

  7. 9-ESP8266 SDK开发基础入门篇--编写串口上位机软件

    https://www.cnblogs.com/yangfengwu/p/11087613.html 页面修改成这样子             现在看串口发送数据 点击点亮 发送0xaa 0x55 0 ...

  8. 23-ESP8266 SDK开发基础入门篇--编写Android TCP客户端 , 加入消息处理

    https://www.cnblogs.com/yangfengwu/p/11203546.html 先做接收消息 然后接着 public class MainActivity extends App ...

  9. 19-ESP8266 SDK开发基础入门篇--C# TCP客户端编写 , 连接和断开

    https://www.cnblogs.com/yangfengwu/p/11130428.html 渐渐的看过去,,,好多节了... 这节做一个C# TCP客户端 新建项目啥子的就不详细截图写了,自 ...

随机推荐

  1. CF1109F Sasha and Algorithm of Silence's Sounds LCT、线段树

    传送门 构成一棵树可以分成两个限制:图不成环.图的点数-边数=1. 我们考虑枚举右端点\(r\)计算所有可能的左端点\(l\)的答案.我们先考虑第一个限制:图不成环.注意到当\(r\)确定的时候,满足 ...

  2. Bootstrap中的datetimepicker用法总结

    bootstrap时间控件参考文档(少走弯路) https://blog.csdn.net/hizzyzzh/article/details/51212867#31-format-%E6%A0%BC% ...

  3. Java——简单实现学生管理系统

    import java.io.*;import java.util.ArrayList;import java.util.Scanner;class MyObjectOutputStream exte ...

  4. 反射之关于MethodInfo的使用

    1.MethodInfo类是在System.Reflection命名空间底下,既然是在Reflection空间底下.故名思议关于反射相关的操作,其中比较重要的方法是Invoke()方法,它是加载相同程 ...

  5. ASP.NET SignalR 系列(一)之SignalR介绍

    一.SignalR介绍 ASP.NET SignalR 是一个面向 ASP.NET 开发人员的库,可简化将实时 web 功能添加到应用程序的过程. 实时 web 功能是让服务器代码将内容推送到连接的客 ...

  6. Python进阶(一)----函数

    Python进阶(一)----函数初识 一丶函数的初识 什么函数: ​ 函数是以功能为导向.一个函数封装一个功能 函数的优点: ​ 1.减少代码的重复性, ​ 2.增强了代码的可读性 二丶函数的结构 ...

  7. Java多线程并发同步执行

    https://www.cnblogs.com/pengdai/p/12026959.html 并发关键字:volatile,final,synchronized Collections: 并发集合 ...

  8. Java -- springboot 配置 freemarker

    1.添加依赖 org.springframework.boot spring-boot-starter-freemarker 2.配置application.properties spring.fre ...

  9. 《我是一只IT小小鸟》(续)读书笔记——第八周

    第三位作者强调了大学阶段规划的重要性,作者初入大学,一切都很新鲜想尝试,却缺乏对学习生活的规划.最终导致的是学习成绩的下降.其实编程也是一样,我们常常感到自己和那些大神的差距,感慨过后,往往也就罢了. ...

  10. Python学习日记(三十四) Mysql数据库篇 二

    外键(Foreign Key) 如果今天有一张表上面有很多职务的信息 我们可以通过使用外键的方式去将两张表产生关联 这样的好处能够节省空间,比方说你今天的职务名称很长,在一张表中就要重复的去写这个职务 ...