OpenEdv-开源电子网

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

TCP server程序发发单个字符出错,发多字符串没有问题

[复制链接]

2

主题

2

帖子

0

精华

新手上路

积分
28
金钱
28
注册时间
2013-12-24
在线时间
1 小时
发表于 2017-8-10 17:08:42 | 显示全部楼层 |阅读模式
5金钱
学习原子哥的TCP server 例程,自己搭建了 TCP Server程序。
用网络调试助手测试:发送区域填写2个字符和多于2字符的数据,发送和接收都没有问题;而且第一次发送数据操过2字符,后面发1个字符也不会出错。
但是每次重新连接后,第一次发送1个字符,后面无论发送多少字符都会出错。发送成功 但是接收区无显示?

程序如下,大神帮新手解惑:

部分main函数:

u8 tcp_server_recvbuf[TCP_SERVER_BUFSIZE];  //
u8 tcp_server_sendbuf[TCP_SERVER_BUFSIZE];  //

tcp_server_init( );
while(1)
{
    xemacif_input(netif);

    if (TcpTmrFlag)
    {
       tcp_tmr();
      TcpTmrFlag = 0;
    }
    if((lwip_server_flag&TCP_NEW_DATA)==TCP_NEW_DATA)
   {
       lwip_server_flag&=~TCP_NEW_DATA;
       memcpy(tcp_server_sendbuf,tcp_server_recvbuf,TCP_SERVER_BUFSIZE);
       lwip_server_flag|=TCP_SEND_DATA;
   }
............
...........
}
//--------------------------------------------------------------------------------------------------------
// tcp_server函数
void tcp_server_init(void)
{
err_t err;  
int re=0;
struct tcp_pcb *tcp_server_pcbbuf;
tcp_server_pcb = tcp_new();
if(tcp_server_pcb!=NULL)
{
  err=tcp_bind(tcp_server_pcb,IP_ADDR_ANY,TCP_SERVER_PORT); //绑定本地IP和端口
  if(err==ERR_OK) //绑定OK
  {
   tcp_server_pcbbuf=tcp_listen(tcp_server_pcb);    //监听
   tcp_accept(tcp_server_pcbbuf,tcp_server_accept);//设置回调函数
    lwip_server_flag|=LWIP_CONNECTED;
   re=0;
  }else re=1;
}else re=1;
if(re==1)
{
  tcp_server_connection_close(tcp_server_pcb,0);
  tcp_server_connection_close(tcp_server_pcbbuf,0);
  memset(tcp_server_pcb,0,sizeof(struct tcp_pcb));
  memset(tcp_server_pcbbuf,0,sizeof(struct tcp_pcb));
}
}
//lwIP tcp_accept()回调函数
err_t tcp_server_accept(void *arg,struct tcp_pcb *newpcb,err_t err)
{
err_t ret_err;
struct tcp_server_struct *es;
  LWIP_UNUSED_ARG(arg);
LWIP_UNUSED_ARG(err);
tcp_setprio(newpcb,TCP_PRIO_MIN);//设置优先级
es=(struct tcp_server_struct*)mem_malloc(sizeof(struct tcp_server_struct)); //分配内存
  if(es!=NULL) //
{//每个连接分配一个状态接口es
  es->state=ES_TCPSERVER_ACCEPTED;   //
  es->pcb=newpcb;
  es->p=NULL;
  tcp_arg(newpcb,es);
  tcp_recv(newpcb,tcp_server_recv); //
  tcp_err(newpcb,tcp_server_error);  //
  tcp_poll(newpcb,tcp_server_poll,1); //
  tcp_sent(newpcb,tcp_server_sent);   //
  //tcp_server_pcb->remote_ip.addr=tpcb->remote_ip.addr;
   tcp_server_pcb->remote_ip=newpcb->remote_ip;
  lwip_server_flag|=LWIP_CONNECTED;    //连接上
  ret_err=ERR_OK;
}else ret_err=ERR_MEM;
return ret_err;
}
//lwIP tcp_recv()接收函数
err_t tcp_server_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
err_t ret_err;
u32 data_len = 0;
struct pbuf *q;
   struct tcp_server_struct *es;
LWIP_ASSERT("arg != NULL",arg != NULL);
es=(struct tcp_server_struct *)arg;
if(p==NULL) //
{
  es->state=ES_TCPSERVER_CLOSING;//
  es->p=p;
  lwip_server_flag &=~ LWIP_CONNECTED;
  ret_err=ERR_OK;
}
else if(err!=ERR_OK) //
{
  if(p)pbuf_free(p); //
  ret_err=err;
}
else if(es->state==ES_TCPSERVER_ACCEPTED)  //
{
  if(p!=NULL)  //
  {
   memset(tcp_server_recvbuf,0,TCP_SERVER_BUFSIZE);  //
   for(q=p;q!=NULL;q=q->next)  //
   {

    if(q->len > (TCP_SERVER_BUFSIZE-data_len))
     memcpy(tcp_server_recvbuf+data_len,q->payload,(TCP_SERVER_BUFSIZE-data_len));//
    else
     memcpy(tcp_server_recvbuf+data_len,q->payload,q->len);

    data_len += q->len;   
    if(data_len > TCP_SERVER_BUFSIZE)
     break; //
   }
      tcp_server_pcb->remote_ip=tpcb->remote_ip;
   lwip_server_flag|= TCP_NEW_DATA; //
    tcp_recved(tpcb,p->tot_len);//
   pbuf_free(p);   //
   ret_err=ERR_OK;
  }
}else//
{
  tcp_recved(tpcb,p->tot_len);//
  es->p=NULL;
  pbuf_free(p); //
  ret_err=ERR_OK;
}
return ret_err;
}
//lwIP tcp_err
void tcp_server_error(void *arg,err_t err)
{  
LWIP_UNUSED_ARG(err);  

if(arg!=NULL)mem_free(arg);//
}
//lwIP tcp_poll
err_t tcp_server_poll(void *arg, struct tcp_pcb *tpcb)
{
err_t ret_err;
struct tcp_server_struct *es;
es=(struct tcp_server_struct *)arg;
if(es!=NULL)
{
  if((lwip_server_flag&TCP_SEND_DATA)==TCP_SEND_DATA) //
  {
   es->p=pbuf_alloc(PBUF_TRANSPORT,strlen((char*)tcp_server_sendbuf),PBUF_POOL);//
   pbuf_take(es->p,(char*)tcp_server_sendbuf,strlen((char*)tcp_server_sendbuf));
   tcp_server_senddata(tpcb,es);   //
   memset(tcp_server_sendbuf,0,TCP_SERVER_BUFSIZE);//tcp_server_sendbuf清零
   lwip_server_flag&=~TCP_SEND_DATA;     //
   if(es->p!=NULL)pbuf_free(es->p);  //
  }else if(es->state==ES_TCPSERVER_CLOSING)//
  {
   tcp_server_connection_close(tpcb,es);//
  }
  ret_err=ERR_OK;
}else
{
  tcp_abort(tpcb);//
  ret_err=ERR_ABRT;
}
return ret_err;
}
//lwIP tcp_sent
err_t tcp_server_sent(void *arg, struct tcp_pcb *tpcb, u16_t len)
{
struct tcp_server_struct *es;
LWIP_UNUSED_ARG(len);
es = (struct tcp_server_struct *) arg;
if(es->p)tcp_server_senddata(tpcb,es);//
return ERR_OK;
}
//
void tcp_server_senddata(struct tcp_pcb *tpcb, struct tcp_server_struct *es)
{
struct pbuf *ptr;
u16 plen;
err_t wr_err=ERR_OK;
  while((wr_err==ERR_OK)&&es->p&&(es->p->len<=tcp_sndbuf(tpcb)))
  {
  ptr=es->p;
  wr_err=tcp_write(tpcb,ptr->payload,ptr->len,1);
  if(wr_err==ERR_OK)
  {
   plen=ptr->len;
   es->p=ptr->next;   //
   if(es->p)pbuf_ref(es->p); //
   pbuf_free(ptr);
   tcp_recved(tpcb,plen);   //
  }else if(wr_err==ERR_MEM)es->p=ptr;
  }
}
//
void tcp_server_connection_close(struct tcp_pcb *tpcb, struct tcp_server_struct *es)
{
tcp_close(tpcb);
tcp_arg(tpcb,NULL);
tcp_sent(tpcb,NULL);
tcp_recv(tpcb,NULL);
tcp_err(tpcb,NULL);
tcp_poll(tpcb,NULL,0);
if(es)mem_free(es);
lwip_server_flag&=~LWIP_CONNECTED;//
}



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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165462
金钱
165462
注册时间
2010-12-1
在线时间
2114 小时
发表于 2017-8-12 00:59:09 | 显示全部楼层
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-4-20 15:08

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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