17-ESP8266 SDK开发基础入门篇--TCP服务器 RTOS版,小试牛刀
https://www.cnblogs.com/yangfengwu/p/11105466.html
现在开始写...
lwip即可以用socket 的API 也可以用 netconn 的API实现网络通信
socket 本身其实就是在netconn 上的再一次封装,所以使用起来更快捷(好多东西又封装了一下),但是由于我以前做的项目都是用的netconn ,所以咱还是用 netconn 实现
毕竟用的更底层,更稳定,更省资源
提到lwip 不得不提一个人 "老衲五木" 大家可以百度 老衲五木LWIP 我当时学习的时候就是看的他的文章,记得几年前我在写一篇文章的时候还吐槽了下
这个大神呢 ,他写文章的时候会扯一扯别的,我也文章的时候也是这样,也不知道为什么,写的很入神了之后遍会油然而生一些感慨.
这位大神的文章我给大家准备好了

现在可以不用去看,,先跟着我学会使用,使用着使用着,如果遇到问题了,那么咱再看文档去解决问题
首先说一下哈,,其实老衲五木给了一个例子,TCP服务器的例子

咱就还是按照先前说的,先学会用,用着用着哪里出现问题了再去看文档
好现在建个任务,,上一篇是用裸机跑的,这次咱用操作系统跑


然后我就不一个一个的这样写了,,我就一段一段的写

void TcpServerThread(void *date)
{
struct netconn *conn, *newconn;//conn 保存自身TCP服务器的信息 newconn-保存连接客户端的信息
err_t err;//有客户端连接以后,会返回这次连接的错误信息 static ip_addr_t ipaddr;//存储客户端的地址
static u16_t port;//存储客户端的端口号 conn = netconn_new(NETCONN_TCP);//创建一个TCP //注意哈,首先要明白你无论创建 TCP服务器或者客户端,或者UDP,你创建的时候必须设置下TCP服务器或者客户端,或者UDP的IP地址和端口号.
//网络之间通信嘛,这是必须的,只有你有IP和端口号了,别人才能和你通信
netconn_bind(conn,IP_ADDR_ANY,); //设置conn(TCP服务器) 的IP地址是自己网卡上的IP 设置TCP服务器通信的端口号是8888 (无论创建 TCP服务器或者客户端,或者UDP,都是必须的) netconn_listen(conn); //使用监听函数,说明是创建TCP服务器,只有作为服务器才是监听客户端连接嘛 //设置任务阻塞时间为10ms (注意哈,这个和(注意哈,这个和vTaskDelay(10/portTICK_RATE_MS)类似,但是一定要用这个
//下面的netconn_accept(conn,&newconn);函数是完全阻塞的,,如果你不设置conn->recv_timeout 程序就停止在那里了,除非有客户端连接
conn->recv_timeout=;//任务延时10ms
while()
{
err = netconn_accept(conn,&newconn);//等待客户端连接,有客户机连接,或者超时了就会往下执行
if (err == ERR_OK)//只有客户机连接了,并且没有其它错误才会进入
{
netconn_getaddr(newconn,&ipaddr,&port,); //得到客户端的IP地址和端口号 最后一个参数 1获取本地IP地址,0获取客户端IP地址
//打印客户端的IP地址
printf("ClientIP:%d.%d.%d.%d\n",(uint8_t)(ipaddr.addr),(uint8_t)(ipaddr.addr >> ),(uint8_t)(ipaddr.addr >> ),(uint8_t)(ipaddr.addr >> ));
printf("Port:%d\n",port);//打印客户端的端口号
netconn_close(newconn);//关闭连接
netconn_delete(newconn);//删除连接
}
else
{
conn->recv_timeout=;//任务延时10ms
}
}
vTaskDelete(NULL);
}
上面实现的是,WIFI创建了TCP 然后设置TCP的IP是自身的IP地址(默认是192.168.4.1) 端口号是8888
然后调用了监听,然后(假设没有客户端连接哈) netconn_accept(conn,&newconn);//等待客户端连接,有客户机连接,或者超时了就会往下执行
从这里等待10ms 然后超时,往下执行
conn->recv_timeout=10;//任务延时10ms 其实也是设置 等待客户机的那个函数超时时间是10ms 然后就是这样循环....
然后如果检测到客户端连接了,获取下客户端的信息,然后打印下,然后关闭连接...然后又是等待连接,然后呢又是任务延时.....循环起来了
现在测试,下载进去WIFI程序
这次安装这个,这个是我当年写的APP,用我的这个是因为,下面的那个不能检测到服务器主动断开了连接......
我的这个做了这个功能
现在做一个功能,客户端发过来什么数据,咱就回复什么数据,同时把接收的数据串口输出
void TcpServerThread(void *date)
{
struct netconn *conn, *newconn;//conn 保存自身TCP服务器的信息 newconn-保存连接客户端的信息
err_t err;//有客户端连接以后,会返回这次连接的错误信息 static ip_addr_t ipaddr;//存储客户端的地址
static u16_t port;//存储客户端的端口号 int i = ;
struct pbuf *q;//用此变量来操作链表,可以看一下 https://www.cnblogs.com/yangfengwu/p/5778872.html
u32 data_len =;//获取接收的数据个数
unsigned char TcpRead[]={};//接收数据缓存的数组,最大接收1024字节 conn = netconn_new(NETCONN_TCP);//创建一个TCP //注意哈,首先要明白你无论创建 TCP服务器或者客户端,或者UDP,你创建的时候必须设置下TCP服务器或者客户端,或者UDP的IP地址和端口号.
//网络之间通信嘛,这是必须的,只有你有IP和端口号了,别人才能和你通信
netconn_bind(conn,IP_ADDR_ANY,); //设置conn(TCP服务器) 的IP地址是自己网卡上的IP 设置TCP服务器通信的端口号是8888 (无论创建 TCP服务器或者客户端,或者UDP,都是必须的) netconn_listen(conn); //使用监听函数,说明是创建TCP服务器,只有作为服务器才是监听客户端连接嘛 //设置任务阻塞时间为10ms (注意哈,这个和vTaskDelay(10/portTICK_RATE_MS)类似,但是一定要用这个
//下面的netconn_accept(conn,&newconn);函数是完全阻塞的,,如果你不设置conn->recv_timeout 程序就停止在那里了,除非有客户端连接
conn->recv_timeout=;//任务延时10ms
while()
{
err = netconn_accept(conn,&newconn);//等待客户端连接,有客户机连接,或者超时了就会往下执行
if (err == ERR_OK)//只有客户机连接了,并且没有其它错误才会进入
{
struct netbuf *recvbuf;//创建接收数据的结构体,这是lwip提供的缓存数据用的
netconn_getaddr(newconn,&ipaddr,&port,); //得到客户端的IP地址和端口号 最后一个参数 1获取本地IP地址,0获取远程IP地址
//打印客户端的IP地址
printf("ClientIP:%d.%d.%d.%d\n",(uint8_t)(ipaddr.addr),(uint8_t)(ipaddr.addr >> ),(uint8_t)(ipaddr.addr >> ),(uint8_t)(ipaddr.addr >> ));
printf("Port:%d\n",port);//打印客户端的端口号
// netconn_close(newconn);//关闭连接
// netconn_delete(newconn);//删除连接 while()//一直在这个里面接收处理数据
{
if((err = netconn_recv(newconn,&recvbuf)) == ERR_OK)//接收到客户端发过来的数据,,这个是阻塞的,,咱上面设置的是10ms超时,,所以每次到这里都会延时10ms(执行别的任务去了)
{
taskENTER_CRITICAL();//关闭中断,禁止其它任务打断,防止读数据出现错误 data_len = ;
for( q = recvbuf->p; q != NULL; q = q->next ) //遍历完整个pbuf链表
{
//判断要拷贝到缓存数组中的数据是否大于缓存数组的剩余空间,如果大于
//的话就只拷贝缓存数组中剩余长度的数据,否则的话就拷贝所有的数据
if( q->len > ( -data_len ) )
memcpy(TcpRead+data_len,q->payload,(-data_len));//拷贝数据
else
memcpy( TcpRead+data_len, q->payload, q->len );
data_len += q->len;
if(data_len > )//超出TCP客户端接收数组,跳出
break;
} taskEXIT_CRITICAL();//打开中断 //newconn--发给这个客户端,发送的数组,发送的个数,最后有好几个取值,具体看文章(太多写不开)
err = netconn_write(newconn ,TcpRead,data_len ,NETCONN_NOCOPY);//发送数据 for(i=;i<data_len;i++)
{
USART_SendData(UART0, TcpRead[i]);//接收的数据发给串口
}
}
}
}
else
{
conn->recv_timeout=;//任务延时10ms
}
}
vTaskDelete(NULL);
}
主要的就两个地方需要说一下
可以看这个 https://www.cnblogs.com/yangfengwu/p/5778872.html还有一个地方
填的是NETCONN_COPY时, 数据将被先复制到内存缓冲区,然后再发送,这样会耽误点时间,还需要开辟内存...但是好处是,
执行完以后就可以随意修改 TcpRead (假设这个是咱发送数据用的哈) 里面的值了.
NETCONN_NOCOPY,发送数据的时候是直接从咱原始数组里面取,然后发送
其它的自己研究哈..测试测试...
好现在测试,下载好WIFI程序哈

好了,先消化消化哈...下节再加上串口的数据转发给TCP
说一下哈,无论用的哪种的编译器或者用的哪个版本,底层应用该怎么用还是怎么用,就像这个lwip,,因为这些都是完全完全通用的...
一句话概括:就是这么用.
有个地方说错了

err = netconn_recv(newconn,&recvbuf); 这是判断接没接收到数据的函数,如果没有接收到数据就不会往下执行
直至接收到数据才往下执行
可以分开看

但是并不是阻塞哈,别的任务照样运行,其实我感觉是内部每隔10ms检测有没有数据过来,没有的话就return
https://www.cnblogs.com/yangfengwu/p/11130428.html
17-ESP8266 SDK开发基础入门篇--TCP服务器 RTOS版,小试牛刀的更多相关文章
- 18-ESP8266 SDK开发基础入门篇--TCP 服务器 RTOS版,串口透传,TCP客户端控制LED
https://www.cnblogs.com/yangfengwu/p/11112015.html 先规定一下协议 aa 55 02 01 F1 4C 控制LED点亮 F1 4C为CRC高位和低位 ...
- 16-ESP8266 SDK开发基础入门篇--TCP 服务器 非RTOS运行版,串口透传(串口回调函数处理版)
https://www.cnblogs.com/yangfengwu/p/11105466.html 其实官方给的RTOS的版本就是在原先非RTOS版本上增加的 https://www.cnblogs ...
- 29-ESP8266 SDK开发基础入门篇--编写TCP 客户端程序(Lwip RAW模式,非RTOS版,精简入门)
https://www.cnblogs.com/yangfengwu/p/11456667.html 由于上一节的源码长时间以后会自动断开,所以再做这一版非RTOS版的,咱直接用lua源码里面别人写的 ...
- 28-ESP8266 SDK开发基础入门篇--编写wifi模块TCP 客户端程序(官方API版,非RTOS版)
https://www.cnblogs.com/yangfengwu/p/11432795.html 注:这节实现的功能是WIFI模块作为TCP 客户端,连接咱的TCP服务器,然后实现透传 本来想着做 ...
- 24-ESP8266 SDK开发基础入门篇--Android TCP客户端.控制 Wi-Fi输出PWM的占空比,调节LED亮度
https://www.cnblogs.com/yangfengwu/p/11204436.html 刚才有人说需要点鸡汤.... 我想想哈;我还没问关于哪方面的鸡汤呢!!! 我所一直走的路线 第一: ...
- 22-ESP8266 SDK开发基础入门篇--编写Android TCP客户端 , 连接和断开
https://www.cnblogs.com/yangfengwu/p/11192618.html 有些很细致的东西参考这篇 https://www.cnblogs.com/yangfengwu ...
- 23-ESP8266 SDK开发基础入门篇--编写Android TCP客户端 , 加入消息处理
https://www.cnblogs.com/yangfengwu/p/11203546.html 先做接收消息 然后接着 public class MainActivity extends App ...
- 1-ESP8266 SDK开发基础入门篇--开发环境搭建
因为今天终于做好了自己的另一块工控板,所以我就开始写基础公开篇的内容,希望自己小小的努力能够帮到大家 自己做的另一块板子 https://www.cnblogs.com/yangfengwu/cate ...
- 25-ESP8266 SDK开发基础入门篇--控制WIFI连接路由器
https://www.cnblogs.com/yangfengwu/p/11324411.html 说个事情,现在SDK的版本已经出到3.0了,但是我还是使用2.0 如果只是为了学习研究 选择3 ...
随机推荐
- 部署.Net Core APi+Vue 到 linux centos 服务器(一)
部署.Net Core APi+Vue 到 linux centos 服务器(一) 前言:项目采用的是 .net core 作为接口,vue作为前端. 此时需要把整个项目架设到linux centos ...
- 魔法 [线段树优化DP]
也许更好的阅读体验 \(\mathcal{Description}\) 小 \(D\) 正在研究魔法. 小 \(D\) 得到了远古时期的魔法咒语 \(S\),这个咒语共有 \(n\) 个音节,每个音节 ...
- C#关键字:访问修饰符
一.访问修饰符 访问修饰符有public.private.protected.internal和protected internal.它们是修饰在类型(类.接口.委托.结构和枚举)和类型成员(字段.属 ...
- Java自学-类和对象 继承
什么是 Java的 继承 ? 在LOL中,武器是物品的一种,也是有名称和价格的 所以在设计类的时候,可以让武器继承物品,从而继承名称和价格属性 步骤 1 : 物品类Item 物品类Item 有属性 n ...
- 30个关于Shell脚本的经典案例(中)
本文目录 11.iptables自动屏蔽访问网站频繁的IP 12.判断用户输入的是否为IP地址 13.判断用户输入的是否为数字 14.给定目录找出包含关键字的文件 15.监控目录,将新创建的文件名追加 ...
- js数组【续】(相关方法)
一.数组的栈,队列方法[调用这些方法原数组会发生改变]var arr = [2,3,4,5,6];1.栈 LIFO (Last-In-First-Out)a.push() 可接受任意类型的参数,将它们 ...
- JAVA基础之会话技术-Cookie及Session
至此,学习Servlet三个域对象:ServletContext(web项目).request(一次请求).Session(一个客户端)!均有相同的方法! 从用户开始打开浏览器进行操作,便开始了一次会 ...
- Flask 和 Django 框架的区别
1)Flask Flask确实很“轻”,不愧是Micro Framework,从Django转向Flask的开发者一定会如此感慨,除非二者均为深入使用过 Flask自由.灵活,可扩展性强,第三方库的选 ...
- Oracle恢复流程图
本图来自于网络,想当初小麦苗刚开始接触备份恢复的时候,就是靠着这张图来学习的,今天把这张图分享给大家,共勉. ............................................. ...
- php的多功能文件操作类
本类为文件操作类,实现了文件的建立,写入,删除,修改,复制,移动,创建目录,删除目录,列出目录里的文件等功能,路径后面别忘了加"/" 创建指定路径下的指定文件 * @param s ...










