Can only one time send from server to client

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Can only one time send from server to client

Mauricio brazuka
    Hello everybody!
    I am LwIP begginer and i try write one program with the LwIP(raw-api) but my program dont run very well.
    My program can send only one time the information from Server to client.
    Why can i write from server to client more that one time with the same connection?
    My program is the adaptation from the programs httpd.c and shell.c LwIP's sources.
    
    Can someone help me please?


  Thanks a lot
  Mauricio
    
    First client example wrinted in Perl only to testing.
    This works only problem
    ##################################################
    # Works                                          #
    ##################################################
    $MySocket=new IO::Socket::INET->new(PeerPort=>80,
      Proto=>'tcp',
      PeerAddr=>$ip_address);
        
    $MySocket->send("WRITE 1 2\n"); // First command
    
    $MySocket=new IO::Socket::INET->new(PeerPort=>80,
      Proto=>'tcp',
      PeerAddr=>$ip_address);
        
    $MySocket->send("WRITE 3 4\n"); // Second command
    #-------------------------------------------------
    
    Second client example wrinted in Perl only to testing
    This works only one time, i can send only the first "command"
    and the second command is not accepted
    ##################################################
    # Dont Work                                      #
    ##################################################
    $MySocket=new IO::Socket::INET->new(PeerPort=>80,
      Proto=>'tcp',
      PeerAddr=>$ip_address);
        
    $MySocket->send("WRITE 1 2\n");
    
    $MySocket->send("WRITE 3 4\n");
    #-------------------------------------------------



/*--------------------------------------------------*/
/* Program shell server                             */
/*--------------------------------------------------*/

#include "lwip/debug.h"

#include "lwip/stats.h"

#include "shell_socket.h"

#include "lwip/tcp.h"

#include "fs.h"

#define ESUCCESS 0
#define ESYNTAX -1
#define ETOOFEW -2
#define ETOOMANY -3
#define ECLOSED -4

static unsigned char buffer[1024];

struct shell_state {
  char *respond;
  u32_t left;
  u8_t retries;
};

struct command {
   struct tcp_pcb *pcb;
   s8_t (* exec)(struct command *, struct shell_state *);
   u8_t nargs;
   char *args[10];
};


/*-----------------------------------------------------------------------------------*/
/* Send String                                                                       */
/*-----------------------------------------------------------------------------------*/
static void
sendstr(const char *str, struct tcp_pcb *pcb)
{
  /*  
  err = tcp_write(pcb, (void *)str, strlen(str), 0);
  */
  tcp_write(pcb, (void *)str, strlen(str), 0);
}
/*************************************************************************************/

/*-----------------------------------------------------------------------------------*/
/* COMMAND: write                                                                    */
/*-----------------------------------------------------------------------------------*/
static s8_t
com_write(struct command *com, struct shell_state *hs)
{
    char com_resp[] = "WRITE_OK";
    
    hs->respond = (char *) com_resp;
    hs->left = strlen(com_resp);
        
  return ESUCCESS;
}
/*************************************************************************************/

/*-----------------------------------------------------------------------------------*/
/* Parse Command                                                                     */
/*-----------------------------------------------------------------------------------*/
static s8_t
parse_command(struct command *com, u32_t len)
{
  u16_t i;
  u16_t bufp;

  if (strncmp((const char *)buffer, "WRITE", 5) == 0) {
      com->exec = com_write;
      com->nargs = 3;
  } else if (strncmp((const char *)buffer, "QUIT", 4) == 0) {
    printf("quit\n");
      return ECLOSED;
  } else {
      return ESYNTAX;
  }

  if (com->nargs == 0) {
  return ESUCCESS;
  }

  bufp = 0;
  for(; bufp < len && buffer[bufp] != ' '; bufp++);
  for(i = 0; i < 10; i++) {
    for(; bufp < len && buffer[bufp] == ' '; bufp++);
    if (buffer[bufp] == '\r' ||
      buffer[bufp] == '\n') {
      buffer[bufp] = 0;
      if (i < com->nargs - 1) {
      return ETOOFEW;
      }
      if (i > com->nargs - 1) {      
      return ETOOMANY;
      }
      break;
    }    
    if (bufp > len) {
      return ETOOFEW;
    }    
    com->args[i] = (char *)&buffer[bufp];

    for(; bufp < len && buffer[bufp] != ' ' && buffer[bufp] != '\r' &&
    buffer[bufp] != '\n'; bufp++) {
      if (buffer[bufp] == '\\') {
  buffer[bufp] = ' ';
      }
    }
    if (bufp > len) {
      return ESYNTAX;
    }
    buffer[bufp] = 0;
    bufp++;
    if (i == com->nargs - 1) {
      break;
    }
  }    
  return ESUCCESS;
}
/*************************************************************************************/

/*-----------------------------------------------------------------------------------*/
/* Error parse command                                                               */
/*-----------------------------------------------------------------------------------*/
static void
error(s8_t err, struct tcp_pcb *pcb)
{
  switch (err) {
  case ESYNTAX:
    sendstr("## Syntax error\n", pcb);
    break;
  case ETOOFEW:
    sendstr("## Too few arguments to command given\n", pcb);
    break;
  case ETOOMANY:
    sendstr("## Too many arguments to command given\n", pcb);
    break;
  }
}
/*************************************************************************************/

/*-----------------------------------------------------------------------------------*/
/* Connection Error                                                                  */
/*-----------------------------------------------------------------------------------*/
static void
conn_err(void *arg, err_t err)
{
  struct shell_state *hs;

  hs = arg;
  mem_free(hs);
}
/*************************************************************************************/

/*-----------------------------------------------------------------------------------*/
/* Close connection                                                                  */
/*-----------------------------------------------------------------------------------*/
static void
close_conn(struct tcp_pcb *pcb, struct shell_state *hs)
{
  tcp_arg(pcb, NULL);
  tcp_sent(pcb, NULL);
  tcp_recv(pcb, NULL);
  mem_free(hs);
  tcp_close(pcb);
}
/*************************************************************************************/

/*-----------------------------------------------------------------------------------*/
/* Send data                                                                         */
/*-----------------------------------------------------------------------------------*/
static void
send_data(struct tcp_pcb *pcb, struct shell_state *hs)
{
  err_t err;
  u16_t len;
    
  /* We cannot send more data than space available in the send
     buffer. */     
  if (tcp_sndbuf(pcb) < hs->left) {
    len = tcp_sndbuf(pcb);
  } else {
    len = hs->left;
  }

  do {
    err = tcp_write(pcb, hs->respond, len, 0);
    /* err = tcp_write(pcb, "TESTANDO\n",11, 0); */
    if (err == ERR_MEM) {
      len /= 2;
    }
  } while (err == ERR_MEM && len > 1);  
 
  if (err == ERR_OK) {
    hs->respond += len;
    hs->left -= len;
  }
}
/*************************************************************************************/

/*-----------------------------------------------------------------------------------*/
/* Shell poll                                                                       */
/*-----------------------------------------------------------------------------------*/
static err_t
shell_poll(void *arg, struct tcp_pcb *pcb)
{
  struct shell_state *hs;

  hs = arg;
 
    if (hs == NULL) {
      tcp_abort(pcb);
    return ERR_ABRT;
  } else {
      ++hs->retries;
    if (hs->retries == 4) {
      tcp_abort(pcb);
    return ERR_ABRT;
    }
    send_data(pcb, hs);
  }

  return ERR_OK;
}
/*************************************************************************************/

/*-----------------------------------------------------------------------------------*/
/* Shell sent                                                                    */
/*-----------------------------------------------------------------------------------*/
static err_t
shell_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
{
  struct shell_state *hs;

  hs = arg;

  hs->retries = 0;
 
  if (hs->left > 0) {    
    send_data(pcb, hs);
  } else {
    close_conn(pcb, hs);
  }

  return ERR_OK;
}
/*************************************************************************************/

/*-----------------------------------------------------------------------------------*/
/* Shell receive                                                                    */
/*-----------------------------------------------------------------------------------*/
static err_t
shell_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
  struct shell_state *hs;
  struct command com;
  char *data;
  char respond[1024];
  s8_t command_error;
  u32_t len;
         
  hs = arg;

  if (err == ERR_OK && p != NULL) {

    /* Inform TCP that we have taken the data. */
    tcp_recved(pcb, p->tot_len);
    
    com.pcb = pcb;
    
    if (hs->respond == NULL) {
      data = p->payload;
      strcpy(buffer, data);
      
      len = strlen(buffer);
      command_error =  parse_command(&com, len);
    
      if (command_error == ESUCCESS) {  
      
            command_error = com.exec(&com, hs);
        
          strcpy(respond,(char *)hs->respond);
            hs->respond = (char *)respond;
         
          pbuf_free(p);
          send_data(pcb, hs);

          /* Tell TCP that we wish be to informed of data that has been
             successfully sent by a call to the shell_sent() function. */
          tcp_sent(pcb, shell_sent);
          
        } else {
           error(command_error, pcb);
         pbuf_free(p);
         close_conn(pcb, hs);
        }
        } else {
            pbuf_free(p);
        }
  }

  if (err == ERR_OK && p == NULL) {
    close_conn(pcb, hs);
  }
  return ERR_OK;
}
/*************************************************************************************/

/*-----------------------------------------------------------------------------------*/
/* Shell accept                                                                     */
/*-----------------------------------------------------------------------------------*/
static err_t
shell_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{
  struct shell_state *hs;

  tcp_setprio(pcb, TCP_PRIO_MIN);
 
  /* Allocate memory for the structure that holds the state of the
     connection. */
  hs = mem_malloc(sizeof(struct shell_state));

  if (hs == NULL) {
    printf("shell_accept: Out of memory\n");
    return ERR_MEM;
  }
 
  /* Initialize the structure. */
  hs->respond = NULL;
  hs->left = 0;
  hs->retries = 0;
 
  /* Tell TCP that this is the structure we wish to be passed for our
     callbacks. */
  tcp_arg(pcb, hs);

  /* Tell TCP that we wish to be informed of incoming data by a call
     to the shell_recv() function. */
  tcp_recv(pcb, shell_recv);
 
  tcp_err(pcb, conn_err);
 
  tcp_poll(pcb, shell_poll, 4);
  return ERR_OK;
}
/*************************************************************************************/

/*-----------------------------------------------------------------------------------*/
/* Shell socket init                                                                */
/*-----------------------------------------------------------------------------------*/

void
shell_socket_init(void)
{
  struct tcp_pcb *pcb;
 
  printf("\nshell_socket_init\n");
  pcb = tcp_new();
  tcp_bind(pcb, IP_ADDR_ANY, 80);
  pcb = tcp_listen(pcb);
  tcp_accept(pcb, shell_accept);
}
/*************************************************************************************/


/***********************************TEST**********************************************/
/*
static void
shell_socket_thread(void *arg)
{
  struct tcp_pcb *pcb;

  pcb = tcp_new();
  tcp_bind(pcb, IP_ADDR_ANY, 80);
  pcb = tcp_listen(pcb);
  while(1) {
  tcp_accept(pcb, shell_accept);
  //tcp_close(pcb);
  }
}
*/

/*-----------------------------------------------------------------------------------*/
/*
void
shell_socket_init(void)     
{
  sys_thread_new(shell_socket_thread, NULL, DEFAULT_THREAD_PRIO);
}
*/
/***********************************TEST**********************************************/


NEU: Fragen stellen - Wissen, Meinungen und Erfahrungen teilen. Jetzt auf Yahoo! Clever.
_______________________________________________
lwip-users mailing list
[hidden email]
http://lists.nongnu.org/mailman/listinfo/lwip-users