Import of the contiki-2.x development code from the SICS internal CVS server
This commit is contained in:
commit
c9e808d638
671 changed files with 95332 additions and 0 deletions
165
doc/example-psock-server.c
Normal file
165
doc/example-psock-server.c
Normal file
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* This is a small example of how to write a TCP server using
|
||||
* Contiki's protosockets. It is a simple server that accepts one line
|
||||
* of text from the TCP connection, and echoes back the first 10 bytes
|
||||
* of the string, and then closes the connection.
|
||||
*
|
||||
* The server only handles one connection at a time.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* We include "contiki-net.h" to get all network definitions and
|
||||
* declarations.
|
||||
*/
|
||||
#include "contiki-net.h"
|
||||
|
||||
/*
|
||||
* We define one protosocket since we've decided to only handle one
|
||||
* connection at a time. If we want to be able to handle more than one
|
||||
* connection at a time, each parallell connection needs its own
|
||||
* protosocket.
|
||||
*/
|
||||
static struct psock ps;
|
||||
|
||||
/*
|
||||
* We must have somewhere to put incoming data, and we use a 10 byte
|
||||
* buffer for this purpose.
|
||||
*/
|
||||
static char buffer[10];
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* A protosocket always requires a protothread. The protothread
|
||||
* contains the code that uses the protosocket. We define the
|
||||
* protothread here.
|
||||
*/
|
||||
static
|
||||
PT_THREAD(handle_connection(struct psock *p))
|
||||
{
|
||||
/*
|
||||
* A protosocket's protothread must start with a PSOCK_BEGIN(), with
|
||||
* the protosocket as argument.
|
||||
*
|
||||
* Remember that the same rules as for protothreads apply: do NOT
|
||||
* use local variables unless you are very sure what you are doing!
|
||||
* Local (stack) variables are not preserved when the protothread
|
||||
* blocks.
|
||||
*/
|
||||
PSOCK_BEGIN(p);
|
||||
|
||||
/*
|
||||
* We start by sending out a welcoming message. The message is sent
|
||||
* using the PSOCK_SEND_STR() function that sends a null-terminated
|
||||
* string.
|
||||
*/
|
||||
PSOCK_SEND_STR(p, "Welcome, please type something and press return.\n");
|
||||
|
||||
/*
|
||||
* Next, we use the PSOCK_READTO() function to read incoming data
|
||||
* from the TCP connection until we get a newline character. The
|
||||
* number of bytes that we actually keep is dependant of the length
|
||||
* of the input buffer that we use. Since we only have a 10 byte
|
||||
* buffer here (the buffer[] array), we can only remember the first
|
||||
* 10 bytes received. The rest of the line up to the newline simply
|
||||
* is discarded.
|
||||
*/
|
||||
PSOCK_READTO(p, '\n');
|
||||
|
||||
/*
|
||||
* And we send back the contents of the buffer. The PSOCK_DATALEN()
|
||||
* function provides us with the length of the data that we've
|
||||
* received. Note that this length will not be longer than the input
|
||||
* buffer we're using.
|
||||
*/
|
||||
PSOCK_SEND_STR(p, "Got the following data: ");
|
||||
PSOCK_SEND(p, buffer, PSOCK_DATALEN(p));
|
||||
PSOCK_SEND_STR(p, "Good bye!\r\n");
|
||||
|
||||
/*
|
||||
* We close the protosocket.
|
||||
*/
|
||||
PSOCK_CLOSE(p);
|
||||
|
||||
/*
|
||||
* And end the protosocket's protothread.
|
||||
*/
|
||||
PSOCK_END(p);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* We declare the process.
|
||||
*/
|
||||
PROCESS(example_psock_server_process, "Example protosocket server");
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* The definition of the process.
|
||||
*/
|
||||
PROCESS_THREAD(example_psock_server_process, ev, data)
|
||||
{
|
||||
/*
|
||||
* The process begins here.
|
||||
*/
|
||||
PROCESS_BEGIN();
|
||||
|
||||
/*
|
||||
* We start with setting up a listening TCP port. Note how we're
|
||||
* using the HTONS() macro to convert the port number (1010) to
|
||||
* network byte order as required by the tcp_listen() function.
|
||||
*/
|
||||
tcp_listen(HTONS(1010));
|
||||
|
||||
/*
|
||||
* We loop for ever, accepting new connections.
|
||||
*/
|
||||
while(1) {
|
||||
|
||||
/*
|
||||
* We wait until we get the first TCP/IP event, which probably
|
||||
* comes because someone connected to us.
|
||||
*/
|
||||
PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event);
|
||||
|
||||
/*
|
||||
* If a peer connected with us, we'll initialize the protosocket
|
||||
* with PSOCK_INIT().
|
||||
*/
|
||||
if(uip_connected()) {
|
||||
|
||||
/*
|
||||
* The PSOCK_INIT() function initializes the protosocket and
|
||||
* binds the input buffer to the protosocket.
|
||||
*/
|
||||
PSOCK_INIT(&ps, buffer, sizeof(buffer));
|
||||
|
||||
/*
|
||||
* We loop until the connection is aborted, closed, or times out.
|
||||
*/
|
||||
while(!(uip_aborted() || uip_closed() || uip_timedout())) {
|
||||
|
||||
/*
|
||||
* We wait until we get a TCP/IP event. Remember that we
|
||||
* always need to wait for events inside a process, to let
|
||||
* other processes run while we are waiting.
|
||||
*/
|
||||
PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event);
|
||||
|
||||
/*
|
||||
* Here is where the real work is taking place: we call the
|
||||
* handle_connection() protothread that we defined above. This
|
||||
* protothread uses the protosocket to receive the data that
|
||||
* we want it to.
|
||||
*/
|
||||
handle_connection(&ps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We must always declare the end of a process.
|
||||
*/
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
Loading…
Add table
Add a link
Reference in a new issue