OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 22509|回复: 11

LWIP做客户端 如何检测服务器断开情况下 重新连接

[复制链接]

57

主题

156

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
451
金钱
451
注册时间
2013-5-23
在线时间
46 小时
发表于 2014-2-18 16:31:21 | 显示全部楼层 |阅读模式
我的程序是参考战舰上面改过来的:按复位键  程序连接两次可以连接上,如果断电重连  就连不上,调试助手 显示1035错误
硬件没问题  因为运行 其他程序 上电和复位是一样的

void  tcp_client_init(void) //服务器初始化函数
{
     struct tcp_client_state* ts;
 struct ip_addr ipaddr; 
 err_t ret_err;
 IP4_ADDR(&ipaddr,192,168,0,122);      //目标IP
 tcp_client_pcb = tcp_new();                        /*  建立通信的 TCP 控制块(Clipcb)               */ 
 tcp_bind( tcp_client_pcb,IP_ADDR_ANY,TCP_CLIENT_PORT);         /*  绑定本地 IP 地址和端口号 不绑定也可以运行 端口号自己分配                      */ 
 if(tcp_client_pcb!=NULL)
{  printf("初始化进入");
     ts = mem_malloc(sizeof(struct tcp_client_state)); //申请内存
   tcp_arg(tcp_client_pcb, ts);   //将程序的协议控制块的状态传递给多有的回调函数
 tcp_connect(tcp_client_pcb,&ipaddr,6000,tcp_client_connect); //连接函数 tcp_client_accept成功连接到主机调用
 tcp_recv(tcp_client_pcb, tcp_client_recv); //指定连接接收到新的数据之后将要调用的回调函数
 tcp_poll(tcp_client_pcb, tcp_client_poll, 2); //轮询函数  发送数据 时间为2/2=1
 
}
 
}
检测状态在主程序中 5S检测一次,connect_net是连接状态标志位
   if(connect_net==1)
 
         printf("开始重新连接   ");
tcp_closed();
tcp_client_init();
if(connect_net==0)  
{
printf("重新连接   ");
}


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

38

主题

2061

帖子

6

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3273
金钱
3273
注册时间
2012-1-16
在线时间
37 小时
发表于 2014-2-18 20:48:12 | 显示全部楼层
回复【楼主位】yangzi6000:
-----------------------------
你参考的是我发的那个例程么?
站在巨人的肩膀上不断的前进。。。
回复 支持 反对

使用道具 举报

57

主题

156

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
451
金钱
451
注册时间
2013-5-23
在线时间
46 小时
 楼主| 发表于 2014-2-20 08:02:49 | 显示全部楼层
回复【2楼】xiaoyan:
---------------------------------
是的   这个问题貌似解决了  ENC28J60的复位时间一定要长 。。。。。。。。。不过例程里面的处理流程 我觉得说的不是很明白,尤其是为什么这样处理,LWIP 我属于菜鸟,见谅
目前客户端测试程序基本稳定  重连也OK  ,现在就是应用中。。。。

还有问题请教
1.做客户端的时候 如何主动发数据 我用tcp_write在采集完数据后发送 不出来  不可能只能在POLL里面循环发吧
2.ethernetif_input(&enc28j60_netif); 多长时间查询一次,连同时间心跳查询可以放到定时器中断里面吗,因为主程序中 有数据采集部分 延时可能长点 
3.tcp_poll(tcp_client_pcb, tcp_client_poll, 0);  后面是0  是什么意思  一般不是2的倍数吗  
4.关闭连接中用到tcp_close(tpcb);   我试着用tcp_abort也可以,那么用tcp_close好处那些
回复 支持 反对

使用道具 举报

38

主题

2061

帖子

6

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3273
金钱
3273
注册时间
2012-1-16
在线时间
37 小时
发表于 2014-2-20 17:28:58 | 显示全部楼层
回复【3楼】yangzi6000:
---------------------------------
1.应该可以发送的,你要确保TCP是连接上的
2.ethernetif_input(&enc28j60_netif); 我在代码中为了保证不掉包,一直查询的。放在定时器中断函数中应该没问题的,这个查询函数,不怎么消耗时间。
3.“一般是2的倍数”不知道你是在哪里看到的。这个参数用来设置查询的间隔,以TCP的周期处理时间为单位。
4.用tcp_abort是终止连接,并没有关闭连接,为他分配的Listening pcbs还是工作的。如果你不用了这个连接建议用tcp_close。
PSWIP 我懂得也不是很多,如果错误请指正,我们一起讨论下。
站在巨人的肩膀上不断的前进。。。
回复 支持 反对

使用道具 举报

12

主题

40

帖子

0

精华

初级会员

Rank: 2

积分
128
金钱
128
注册时间
2014-3-25
在线时间
9 小时
发表于 2014-3-25 11:29:32 | 显示全部楼层
楼主在吗?connect_net 这个是哪个函数的返回值?
你用哪个函数判断网络连接还在不在的?
回复 支持 反对

使用道具 举报

2

主题

13

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2014-7-7
在线时间
1 小时
发表于 2014-7-18 10:16:34 | 显示全部楼层
楼主你移植到mini开发板的吗?能不能指点下
回复 支持 反对

使用道具 举报

3

主题

54

帖子

0

精华

初级会员

Rank: 2

积分
87
金钱
87
注册时间
2014-5-18
在线时间
0 小时
发表于 2014-8-6 16:07:51 | 显示全部楼层
回复【3楼】yangzi6000:
---------------------------------
关于客户端重连的问题能发个程序共享下不?谢谢!
回复 支持 反对

使用道具 举报

3

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
132
金钱
132
注册时间
2014-3-20
在线时间
34 小时
发表于 2016-6-14 09:10:48 | 显示全部楼层
楼主,请问下,我也是用LWIP,发现发送一段时间就发送不出去,已经调用了tcp_write,但是发送不出去,然后我就在这里close_pcb,然后重连,再发送一段时间,重复几次后就再也连接不上服务器了!
回复 支持 反对

使用道具 举报

0

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2014-9-26
在线时间
8 小时
发表于 2016-6-14 13:47:32 | 显示全部楼层
static err_t tcp_echoclient_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
  struct echoclient *es;
  err_t ret_err;
  

  LWIP_ASSERT("arg != NULL",arg != NULL);
  
  es = (struct echoclient *)arg;
  
  /* if we receive an empty tcp frame from server => close connection */
if (p == NULL)
  {
    /* remote host closed connection */
    es->state = ES_CLOSING;
    if(es->p_tx == NULL)
    {
       /* we're done sending, close connection */
       tcp_echoclient_connection_close(tpcb, es);
    }
    else
    {   
      /* send remaining data*/
      tcp_echoclient_send(tpcb, es);
    }
    ret_err = ERR_OK;
  }   
  /* else : a non empty frame was received from echo server but for some reason err != ERR_OK */
  else if(err != ERR_OK)
  {
    /* free received pbuf*/
    if (p != NULL)
    {
      pbuf_free(p);
    }
    ret_err = err;
  }
  else if(es->state == ES_CONNECTED)
  {
    /* increment message count */
    message_count++;
         
    /* Acknowledge data reception */
    tcp_recved(tpcb, p->tot_len);  
   
    pbuf_free(p);
    tcp_echoclient_connection_close(tpcb, es);
    ret_err = ERR_OK;
  }

  /* data received when connection already closed */
  else
  {
    /* Acknowledge data reception */
    tcp_recved(tpcb, p->tot_len);
   
    /* free pbuf and do nothing */
    pbuf_free(p);
    ret_err = ERR_OK;
  }
  return ret_err;
}
标色的就是检测到连接断开。
回复 支持 反对

使用道具 举报

0

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2014-9-26
在线时间
8 小时
发表于 2016-6-14 13:48:43 | 显示全部楼层
static err_t tcp_echoclient_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
  struct echoclient *es;
  err_t ret_err;
  

  LWIP_ASSERT("arg != NULL",arg != NULL);
  
  es = (struct echoclient *)arg;
  
  /* if we receive an empty tcp frame from server => close connection */
  if (p == NULL)
  {
    /* remote host closed connection */
    es->state = ES_CLOSING;
    if(es->p_tx == NULL)
    {
       /* we're done sending, close connection */
       tcp_echoclient_connection_close(tpcb, es);
    }
    else
    {   
      /* send remaining data*/
      tcp_echoclient_send(tpcb, es);
    }
    ret_err = ERR_OK;
  }   
  /* else : a non empty frame was received from echo server but for some reason err != ERR_OK */
  else if(err != ERR_OK)
  {
    /* free received pbuf*/
    if (p != NULL)
    {
      pbuf_free(p);
    }
    ret_err = err;
  }
  else if(es->state == ES_CONNECTED)
  {
    /* increment message count */
    message_count++;
         
    /* Acknowledge data reception */
    tcp_recved(tpcb, p->tot_len);  
   
    pbuf_free(p);
    tcp_echoclient_connection_close(tpcb, es);
    ret_err = ERR_OK;
  }

  /* data received when connection already closed */
  else
  {
    /* Acknowledge data reception */
    tcp_recved(tpcb, p->tot_len);
   
    /* free pbuf and do nothing */
    pbuf_free(p);
    ret_err = ERR_OK;
  }
  return ret_err;
}
上面标错地方了。。
回复 支持 反对

使用道具 举报

3

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
132
金钱
132
注册时间
2014-3-20
在线时间
34 小时
发表于 2016-6-14 15:14:18 | 显示全部楼层
穹鸟无痕 发表于 2016-6-14 13:48
static err_t tcp_echoclient_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
   ...

我检测到断开连接,前面几次可以重连上,但是之后就重连不上了!
回复 支持 反对

使用道具 举报

1

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2017-1-7
在线时间
61 小时
发表于 2017-9-2 14:32:55 | 显示全部楼层
rosewoman 发表于 2016-6-14 15:14
我检测到断开连接,前面几次可以重连上,但是之后就重连不上了!

我也是多少次断开网线后,不能重新连接上PC的服务器端。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-4-18 17:59

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表