收不到ACK超时终止文件传输
ST提供的例程做IAP时STM32是做tftp服务器的。因项目需要,我们需要STM32做客户端。主要的程序如下:
UDPpcb = udp_new();
if (UDPpcb != NULL)
{
/*assign destination IP address */
IP4_ADDR( &dest_ip, 192, 9, 50, 224 );
/* configure destination IP address and port */
err= udp_connect(UDPpcb, &dest_ip, 69);
if (err == ERR_OK)
{
/* Set a receive callback for the upcb */
udp_recv(UDPpcb, tftp_recv_callback, NULL);
len = sprintf (data, "%c%c%s%c%s%c", 0x00, TFTP_RRQ, "app.bin", 0x00, "octet", 0x00);
/* allocate pbuf from pool*/
p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_POOL);
if (p != NULL)
{
/* copy data to pbuf */
pbuf_take(p, (char*)data, len);
/* send udp data */
udp_send(UDPpcb, p);
/* free pbuf */
pbuf_free(p);
}
else
{
printf("Can not allocate pbuf\r\n");
}
}
但在测试中发现tftp_recv_callback从来没被调用,导致服务器端收不到ACK而超时终止文件传输 服务器IP搞对了?
对的, 上面那图已显示收到客户端发来的读文件请求.
捕获.JPG (67.77 KB, 下载次数: 0)
下载附件保存到相册
2015-12-23 16:44 上传
再附上中间过程的一张图.
STM32做服务器时需要先用69端口来侦听, 有客户端连上来的时候再创建一个UDP和客户端通信.
做客户端应该不需要这样做吧, 只需刚开始建立的UDP来通信就可以了? 贴个我设置的
/* 69 is the port used for TFTP protocol initial transaction */
uint16_t port = 69;
/* Create a new UDP control block */
upcb = udp_new();
if(upcb != NULL)
{
/* assign destination IP address */
IP4_ADDR(&destIPaddr, DEST_IP_ADDR0, DEST_IP_ADDR1, DEST_IP_ADDR2, DEST_IP_ADDR3);
/* configure destination IP address and port */
err = udp_connect(upcb, &destIPaddr, port);
if(err == ERR_OK)
{
/* Set a receive callback for the upcb */
udp_recv(upcb, app_tftp_recv_callback, NULL);
//sprintf((char*)data, "sending udp client message %d", (int*)message_count);
pstr = &data;
message_count = 0;
*pstr++ = 0x00;
*pstr++ = TFTP_RRQ; //读报文
//*pstr++ = TFTP_WRQ; //写报文
tm_strcpy(pstr, "999407.bin");
pstr += (strlen("999407.bin") + 1);
tm_strcpy(pstr, "octet");
pstr += (strlen("octet") + 1);
tm_strcpy(pstr, "blksize");
pstr += (strlen("blksize") + 1);
memset(buf, 0x00, sizeof(buf));
sprintf((char*)buf, "%d", 512);
tm_strcpy(pstr, buf);
pstr += (tm_strlen(buf) + 1);
tm_strcpy(pstr, "tsize");
message_count += strlen("tsize");
pstr += (strlen("tsize") + 1);
memset(buf, 0x00, sizeof(buf));
sprintf((char*)buf, "%d", 0);
tm_strcpy(pstr, buf);
pstr += (tm_strlen(buf) + 1);
message_count = pstr - &data;
/* allocate pbuf from pool */
p = pbuf_alloc(PBUF_TRANSPORT, message_count, PBUF_POOL);
if(p != NULL)
{
/* copy data to pbuf */
pbuf_take(p, (char*)data, message_count);
/* send udp data */
udp_send(upcb, p);
/* free pbuf */
pbuf_free(p);
}
else
{
}
}
else
{
}
}
else
{
} 这个是网络传输数据吗?地址好像是Localhost。
照你的设置, 结果还是一样.
为什么你的port是4096?????不是69吗?
客户端连接服务端的69端口, 客户端不一定要用69端口吧.
就象服务端69端口收到客户端的请求, 重新开一个空闲端口与客户端通信一样.
你的程序服务端打印出来的客户端口是69? 不懂,这个玩的比较高大上,支持下。
没有ACK信号?
应该是服务器设置好IP地址和端口号侦听客户端,客户端连接服务器IP地址和端口号后就可以了
话说楼主用的PC工具软件调试服务器好用,调试客户端好用吗?
我现在PC做客户端, STM32做服务端是可以在线升级成功的.
反过来就碰到现在这个问题了. 不知问题出在哪里? 郁闷...
tftpd32这个软件做客户端的时候, 好像就没有log输出了. TFTP32做服务器好用?我调试客户端时没用这个软件
好用, 同时升级几百台没问题, 我们别的项目上用了.
所以这个项目也打算继续用, 但现在不知道问题出在哪里.:'(
你用什么调试的, 调试信息多吗 1、TCP/IP协议栈LWIP1.1、LWIP认识
LWIP是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈,是Light Weight (轻型)IP协议,有无操作系统的支持都可以运行。LWIP提供三种API,分别是RAW API、LWIP API 、BSD API。其中RAW API把协议栈和应用程序放到一个进程里边,该接口基于函数回调技术来实现的,适合于无操作系统的场合运行,如单片机。本文使用的就是LWIP的RAW API来实现网络层的通信的。
1.2、TFTP在LWIP中的实现 关于LWIP的移植,就不在本文中多讲,读者可以在网上找到众多资料或在另外的专题中再详细讲解,在这里我们专注其应用。在LWIP中实现一个TFTP服务器非常简单,根据RAW API的编程方法,在初始化的时候创建一个UDP PCB(TFTP使用UDP协议通信),且绑定69端口(TFTP默认通信端口),最后指定该UDP PCB的数据接收回调函数即可。
以上的创建TFTP服务器的方法需要在LWIP初始化,并启动网卡后进行:
LwIP_Config();
printf("ipaddr:%d.%d.%d.%d\r\n", net_ip, net_ip, net_ip, net_ip);
tftpd_init(); 在tftpd_init函数中创建TFTP服务器: