lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] sending data from spartan3 to another


From: David Empson
Subject: Re: [lwip-users] sending data from spartan3 to another
Date: Thu, 05 Feb 2009 18:07:31 +1300

"devesh" <address@hidden> wrote:
I have been facing a problem as I told earlier. I want to send an 2-D
array of 128X128 (say:char img[128][128]) from one Spartan board to
another. I am able to send 32bytes with the following code. But at
receiving end, I got 24bytes(8 bytes are being lost) only. When i
exceed from 32,I get nothing.
So I concluded that the max bytes can be transferred are 24. But how
can I send 128X128? Through loop?
Well, I am using RAW api of LWIP and edk on WinXP

//FROM SENDER
static err_t client_connected(void *arg, struct tcp_pcb *pcb, err_t err)
{
  int i;
  char test[32];
  //char *string = "Hello!";
  char LWIP_UNUSED_ARG(arg);

  for(i=0;i<32;i++)
  {
test[i]='1';
  }
  test[i-9]='A';
  test[32]='\0';
  xil_printf("The Payload is %s \n\r",test);
  if (err != ERR_OK)

printf("\nclient_connected(): err argument not set to ERR_OK, but is
value is %d\n", err);

  else
  {
      tcp_sent(pcb, client_sent);
      tcp_write(pcb, test, strlen(test), 0);
  }

  return err;
}

I see two obvious problems with the above code.

1. The array is exactly 32 chars long, but you are trying to write to element 32, which is one byte past the end of the array. You should increase test[] to be 33 bytes if you want to send a string of 32 bytes and use a NUL terminator to mark the end. The fact you are writing off the end of the array might explain other odd behaviour, because you will be overwriting something else on the stack - either another variable or something critical like the stack frame for the function.

2. You are calling tcp_write() with the 'copy' parameter set to 0 (false). This tells LWIP that your data does not need to be copied by LWIP and it will continue to exist until the send is complete. This is not true for an automatic variable, so I would expect some random data to be sent if that part of the stack gets used again. You should either declare your test[] array as static, or set the copy parameter to 1 (true) so LWIP will copy the data into a pbuf.

I can't see any obvious explanation for this code sending fewer than 32 bytes, unless it is a side effect of running off the end of the buffer.

//FROM RECEIVING SIDE
err_t recv_callback(void *arg, struct tcp_pcb *tpcb,
                              struct pbuf *p, err_t err)
{

/* do not read the packet if we are not in ESTABLISHED state */
#if 0
if (tpcb->state >= 5 && tpcb->state <= 8) {
tcp_close(tpcb);
if (p)
pbuf_free(p);
//xil_printf("Connection (%d) closed\n\r", (int)(arg));
return;
} else if (tpcb->state > 8)
return;
#else
if (!p) {
tcp_close(tpcb);
tcp_recv(tpcb, NULL);
return ERR_OK;
}
#endif

/* indicate that the packet has been received */
tcp_recved(tpcb, p->len);
int n=32;
/* echo back the payload */
/* in this case, we assume that the payload is < TCP_SND_BUF */
if (tcp_sndbuf(tpcb) > p->len) {
char testing[100];
strncpy(testing, p->payload,p->len);
testing[p->len]='\0';
xil_printf("The actual Payload is %s\n\r",p->payload);
xil_printf("The Payload is %s \n\r",testing);
xil_printf("The Payload on %d is %c \n\r",n-9,testing[n-9]);
xil_printf("The Reference is %d\n\r",p->ref);
xil_printf("The Length of packet is %d\n\r",p->len);
xil_printf("Remote Port Number :: %d\n\r",tpcb->remote_port);
xil_printf("Local Port Number :: %d\n\r",tpcb->local_port);
err = tcp_write(tpcb, p->payload, p->len, 1);
} else
print("no space in tcp_sndbuf\n\r");

/* free the received pbuf */
pbuf_free(p);

return ERR_OK;
}

So this code is receiving one pbuf's worth of data and sending it back again.

An obvious potential explanation for your observed behaviour is if the receiver is using very small pbufs (which can hold in the order of 8 bytes). You would only get the data in the first pbuf using this code. Similarly, if the sender is using very small pbufs or the receive window is small, you will only receive a short burst of data.

TCP doesn't guarantee any particular delivery pattern for data. You can't assume that writing N bytes on the sender will come out as a single block of N bytes at the receiver. Multiple writes may be collected together and sent in a single packet, a single write may be split into multiple packets, or some combination of the two.

Can you send a copy of your lwipopts.h file to the mailing list? This might explain some of the behaviour you are observing.

In a later message, you wrote:
Well I used sizeof(string) instead of strlen, but the problem was - I
got only 4 bytes on receiver side.

This might be explained if your 'string' was a pointer variable. sizeof(pointer) is 4 on a 32-bit processor.

However, whenever I used some integer :
tcp_write(pcb, test, 1024*1024, 0);

I got the ack that 1024 bytes sent.But could not received by receiver end.

You probably can't write a megabyte in a single operation. Your send buffer isn't likely to be that big.

I am using XILINX and dont know how to set TCP_SND_BUF?? :(

It is defined in lwipopts.h.

Ya,my interface(network) is working correctly. And, the bytes are
being lost in such a way:
1. when I sent 24 I got 16.
2. when I sent 16 I got 8

Where are these 8 bytes going? (and these are not zeros)

Very odd. Nothing springs to mind.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]