[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lwip-users] Re: [lwip] Problems with TCP
From: |
Rajaraman Krishnan |
Subject: |
[lwip-users] Re: [lwip] Problems with TCP |
Date: |
Thu, 09 Jan 2003 01:34:55 -0000 |
This is a multi-part message in MIME format.
------=_NextPart_000_0029_01C1B16A.ACFFCEA0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Hi Adam,
Thanks for answering my question. That solved the problem. I am now able to
run the TCP server on the LwIP stack and the client on the normal Linux IP
stack over the TAP/TUN interface. However I now have problem when I try it
the otherway around. i.e. I have a TCP client implemented over the LwIP
stack and the server on the Linux IP stack.
When I issue a tcp_connect on the LwIP side, I get these messages "Send ARP
after query" a few times and then my HandleConnect() call gets called with
an error. It seems like the Linux stack is not responding to the ARPs. All I
was doing to initialise this interface was call the tapif_init on the LwIP
side. Is anything more required?
Anyway I got around this problem by explicitly pinging this LwIP node from
another window in the Linux machine. That I figured would eliminate the need
for ARP. It did fix that problem. But then I get the following message when
I try to write to this connection,
Assertion "tcp_enqueue: valid queue length" failed at line 178 in
/home/rajaram/utils/lwip-0.5.0/src/core/tcp_output.c
Aborted
Thanks,
Rajaram
----- Original Message -----
From: "Adam Dunkels" <address@hidden>
To: <address@hidden>
Sent: Friday, February 08, 2002 6:56 PM
Subject: Re: [lwip] Problems with TCP
> Hi!
>
> On Thursday 07 February 2002 08.55, you wrote:
> > Can someone throw some light on what is going on? BTW I did think about
> > using the TCP code from shell.c but that doesnt use the Raw API and the
API
> > it uses (i.e. netconn_*) is not documented anywhere.
>
> The problem is because your HandleNewConnection() function blocks on
> sys_sem_wait(). Since this function is executed in the TCP/IP thread, it
must
> not block, since this will block the entire TCP/IP stack. The raw API
> requires a slight mindshift from the threaded programming model to the
> callback/event based model.
>
> In your case, you shouldn't wait for the semaphore. Instead, you should
put
> the code that comes after sys_sem_wait() in your ReadSocket() function.
>
> The sequential API (netconn_*) is documented in the paper found in the
> "Documentation" section on the lwIP homepage. Since programs using the
> sequential API runs in a different thread from the TCP/IP stack, there are
no
> problems with blocking there.
>
> /adam
> --
> Adam Dunkels <address@hidden>
> http://www.sics.se/~adam
> [This message was sent through the lwip discussion list.]
>
------=_NextPart_000_0029_01C1B16A.ACFFCEA0
Content-Type: application/octet-stream;
name="server.cc"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="server.cc"
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#define MAX_STRING 100
int sockfd;
// Send a buffer to the Wrapper.
int WriteSocket(char *msg)
{
ulong bufLen =3D strlen(msg)+1;
ulong tmpLen, writeLen =3D 0;
while (writeLen < bufLen)
{
if ((tmpLen =3D write(sockfd, msg+writeLen, bufLen)) <=3D 0)
{
printf("write error\n");
return 1;
}
writeLen +=3D tmpLen;
}
return 0;
}
// Read the message from socket
// Read the message from socket
int ReadSocket(char *msg)
{
ulong tmpLen, readLen =3D 0;
while (1)
{
if ((tmpLen =3D read(sockfd, msg+readLen, MAX_STRING)) <=3D 0)
{
printf("read error\n");
return 1;
}
printf("Read Something.\n");
readLen +=3D tmpLen;
if (msg[readLen-1] =3D=3D '\0') return 0;
}
}
/*-----------------------------------------------------------------------=
----
| Setup socket
|------------------------------------------------------------------------=
--*/
void SetupServerSocket(char* name, int port)=20
{
/* start the socket server */
struct sockaddr_in addr, peer;
socklen_t sockAddrLen, peerAddrLen;
/* create what looks like an ordinary UDP socket */
if ((sockfd=3Dsocket(AF_INET,SOCK_STREAM,0)) < 0)
{
perror("socket");
exit(1);
}
=20
/* set up destination address */
memset(&addr,0,sizeof(addr));
addr.sin_family=3DAF_INET;
addr.sin_addr.s_addr=3Dhtonl(INADDR_ANY);
addr.sin_port=3Dhtons(port);
/* bind to receive address */
if (bind(sockfd,(struct sockaddr *) &addr,sizeof(addr)) < 0)
{
perror("bind failed: ");
exit(1);
}
=20
/* listen to the socket */
printf("Bind OK. Listening for connect.\n");
listen(sockfd, 5);
peerAddrLen =3D sizeof(peer);
/* accept the socket, and create a peer socket to listen */
if ((sockfd =3D accept(sockfd, (struct sockaddr *)&peer, =
&peerAddrLen)) < 0 )
{
perror("accept");
exit(1);
}
printf("Connected.\n");
}
main(int argc, char **argv)
{
ulong port;
char msg[MAX_STRING];
if (argc !=3D 2)
{
printf("Usage: %s <portNo>\n", argv[0]);
exit(1);
}
if (sscanf(argv[1], "%d", &port) !=3D 1)
{
printf("Usage: %s <portNo>\n", argv[0]);
exit(1);
}
printf("Binding the socket and listening on port %d.\n", port);
SetupServerSocket(argv[2], port);
printf("Receiving message from client.\n");
ReadSocket(msg);
printf("Message Received: %s. \nSending Reply: Hi2U2.\n", msg);
WriteSocket("Hi2U2Hi2U2");
printf("Message Sent.\n");
}
------=_NextPart_000_0029_01C1B16A.ACFFCEA0
Content-Type: application/octet-stream;
name="lwip_client.c"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="lwip_client.c"
#include "lwip/debug.h"
#include <unistd.h>
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/sys.h"
#include "lwip/stats.h"
#include "lwip/tcpip.h"
#include "netif/tapif.h"
#include "netif/tunif.h"
#include "netif/unixif.h"
#include "netif/dropif.h"
#include "netif/loopif.h"
#include "netif/tcpdump.h"
#include "netif/sioslipif.h"
#include "lwip/ip_addr.h"
#include <stdio.h>
#define MAX_STRING 100
typedef struct
{
char msg[MAX_STRING];
int len;
} ReceiveDetails;
struct ip_addr host, gw;
int port;
// Read the message from socket
err_t ReadSocket(void * arg, struct tcp_pcb *dsock, struct pbuf *p, =
err_t err)
{
struct pbuf* np;
ReceiveDetails *recv =3D (ReceiveDetails *)arg;
printf("Data to be read in connection.\n");
if (err !=3D 0)
{
printf("Error in HandleNewConn.\n");
exit(1);
}
if (p =3D=3D NULL)
{
printf("Server closed connection.\n");
/* Close the Dsock. */
tcp_close(dsock);
exit(1);
}
np =3D p;
while (np !=3D NULL)
{
printf("Processing packet at %p.\n", np);
printf("Processing packet of length: %d of total %d at %d.\n",
np->len, np->tot_len, recv->len);
memcpy(recv->msg+recv->len, np->payload, np->len);
recv->len +=3D np->len;
np =3D np->next;
}
printf("Received all bufs. Total len =3D %d.\n", recv->len);
tcp_recved(dsock, p->tot_len);
/* Check if a full string has been received. */
if (recv->msg[recv->len-1] =3D=3D '\0')
{
printf("Message Received: %s. \nSending Reply: Hi2U2.\n", recv->msg);
tcp_close(dsock);
exit(0);
}
return 0;
}
err_t HandleConnect(void *arg, struct tcp_pcb *dsock, err_t err)
{
ReceiveDetails *recv;
recv =3D (ReceiveDetails *) malloc(sizeof(ReceiveDetails));
if (err !=3D 0)
{
printf("Error in HandleNewConn.\n");
exit(1);
}
printf("Connected.\n");
printf("Sending message to Server: Hello.\n");
tcp_write(dsock, "Hello", 6, 1);
printf("Message Sent.\n");
recv->len =3D 0;
tcp_arg(dsock, recv);
tcp_recv(dsock, ReadSocket);
return 0;
}
/*-----------------------------------------------------------------------=
----
| Setup socket
|------------------------------------------------------------------------=
--*/
void TcpCommunicate(int port)=20
{
struct tcp_pcb *sock;
/* create what looks like an ordinary TCP socket */
if ((sock =3D tcp_new()) =3D=3D NULL)
{
printf("Problems with tcp_new.\n");
exit(1);
}
printf("Connecting to %d.%d.%d.%d on port %d.\n",=20
(u8_t)(ntohl(gw.addr) >> 24) & 0xff, \
(u8_t)(ntohl(gw.addr) >> 16) & 0xff, \
(u8_t)(ntohl(gw.addr) >> 8) & 0xff, \
(u8_t)ntohl(gw.addr) & 0xff, port);
if (tcp_connect(sock, &gw, port, HandleConnect))
{
printf("Problems with tcp_connect.\n");
exit(1);
}
}
void lwip_if_init()
{
struct ip_addr lbaddr, netmask, lbgw;
=20
IP4_ADDR(&netmask, 255,255,255,0);
=20
netif_set_default(netif_add(&host, &netmask, &gw, tapif_init,
tcpip_input));
IP4_ADDR(&lbgw, 127,0,0,1);
IP4_ADDR(&lbaddr, 127,0,0,1);
IP4_ADDR(&netmask, 255,0,0,0);
=20
netif_add(&lbaddr, &netmask, &lbgw, loopif_init, tcpip_input);
}
static void
tcpip_init_done(void *arg)
{
sys_sem_t *sem;
sem =3D arg;
sys_sem_signal(*sem);
} =20
void lwip_init()
{
sys_init();
mem_init();
memp_init();
pbuf_init();
}
void main_thread(void *arg)
{
char tmp[MAX_STRING];
sys_sem_t sem;
lwip_if_init();
sem =3D sys_sem_new(0);
tcpip_init(tcpip_init_done, &sem);
sys_sem_wait(sem);
sys_sem_free(sem);
printf("TCP/IP initialized.\n"
"Hit <RETURN> to proceed.");
fflush(stdin);
fgets(tmp, MAX_STRING, stdin);
TcpCommunicate(port);
/* Block for ever. */
sem =3D sys_sem_new(0);
sys_sem_wait(sem);
}
int parse_addr(char *caddr, struct ip_addr *ipaddr1, struct ip_addr =
*ipaddr2)
{
int a, b, c, d;
if (sscanf(caddr, "%d.%d.%d.%d", &a, &b, &c, &d) !=3D 4)
return 0;
if ((a < 0) || (a > 255) || (b < 0) || (b > 255) || (c < 0) || (c > =
255) ||
(d < 0) || (d > 254))
return 0;
IP4_ADDR(ipaddr1, a, b, c, d);
IP4_ADDR(ipaddr2, a, b, c, (d+1));
return 1;
}
int main(int argc, char **argv)
{
if (argc !=3D 3)
{
printf("Usage: %s <Sim IP Address> <portNo>\n", argv[0]);
exit(1);
}
if (!parse_addr(argv[1], &host, &gw))
{
printf("Usage: %s <Sim IP Address> <portNo>\n", argv[0]);
printf("\t<Sim IP Address> should be of the form A.B.C.D.\n");
exit(1);
}
lwip_init();
printf("System initialized.\n");
if (sscanf(argv[2], "%d", &port) !=3D 1)
{
printf("Usage: %s <Sim IP Address> <portNo>\n", argv[0]);
printf("\t<Sim IP Address> should be of the form A.B.C.D.\n");
exit(1);
}
sys_thread_new((void *)(main_thread), NULL);
pause();
return 0;
}
------=_NextPart_000_0029_01C1B16A.ACFFCEA0--
[This message was sent through the lwip discussion list.]