Difference between revisions of "Peerd.c"

From Organic Design wiki
(define globals at start)
(oops, must have pasted wrong code)
Line 1: Line 1:
 
// This article and all its includes are licenced under LGPL
 
// This article and all its includes are licenced under LGPL
 
// GPL: http://www.gnu.org/copyleft/lesser.html
 
// GPL: http://www.gnu.org/copyleft/lesser.html
// SRC: http://www.organicdesign.co.nz/server.c
+
// SRC: http://www.organicdesign.co.nz/husk.c
  
#define DELAY 1        // normal operation is 0 for no delay
+
#include <unistd.h>
#define PAKSIZE 128    // keep packet-size small for non-multithreaded design
+
#include <stdlib.h>
#define BUFSIZE 10000   // dictates max message size
+
#include <stdio.h>
#define MAXCLIENTS 1000 // used by listen()
+
#include <string.h>
 +
#include "SDL/SDL.h"
 +
#include "SDL/SDL_image.h"
 +
#if __WIN32__
 +
#include <winsock2.h>
 +
#else
 +
#include <sys/socket.h>
 +
#include <sys/select.h>
 +
#include <netinet/in.h>
 +
#include <sys/time.h>   // for select()
 +
#include <fcntl.h>      // O_RDWR, O_NONBLOCK, F_GETFL, F_SETFL
 +
#endif
  
// Set up structures for socket & select
+
// Globals
struct sockaddr_in addr;
+
int port = 8000;
struct timeval to;
+
int err = 0;
fd_set *fdset;
+
int this = 0;
unsigned long int sockopt_on = 1;
+
char *peer = "test";
int sock, szAddr = sizeof(struct sockaddr_in);
+
//
memset((char*)&addr, 0, szAddr); // zero the struct
+
int main(int argc, char **argv) {
addr.sin_family = PF_INET;
 
addr.sin_port = htons(port);
 
addr.sin_addr.s_addr = htonl(INADDR_ANY);
 
  
// struct for a stream-node's state to point to
+
#include "util.c"      // General utils, file,log,string etc
typedef struct siStruct {
 
int fd, inptr, outptr;
 
char *inbuf, *outbuf;
 
} streamInfo;
 
  
// make the passed socket non-blocking so accept() returns straight away for multiplexed model
+
#if __WIN32__          // Set up as a daemon or service
// - if no incoming requests, returns EAGAIN or EWOULDBLOCK state
+
#include "servicate.c"
int nonblocking(int socket) {
+
#elif __UNIX__
#if __WIN32__
+
#include "daemonise.c"
ioctlsocket(socket,FIONBIO,&sockopt_on);
 
#else
 
fcntl(socket,F_SETFL,fcntl(socket,F_GETFL)|O_NONBLOCK);
 
 
#endif
 
#endif
return socket;
 
}
 
  
// Do the usual socket polava: create,options,bind,listen
+
#include "listSpace.c"  // listSpace and some C-specific extras: hash, trie, linked-list
err = 0;
+
#include "args.c"      // Handle command-line args and globals like peer and port
if ((sock = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP))<0) logErr("socket() failed!");
+
#include "nodeSpace.c" // NodeSpace function declarations and initialisation
if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char*)&sockopt_on,sizeof(int))<0) logErr("setsockopt() failed!");
+
#include "serialise.c" // Nodal-to-text and visa-versa
if (bind(nonblocking(sock),(struct sockaddr*)&addr,szAddr)<0) logErr("bind() failed!");
+
#include "interface.c" // Layer model (currently bitmap/imagemap-based)
if (listen(sock,MAXCLIENTS)<0) logErr("listen() failed!");
+
#include "server.c"     // Set up listening socket and declare serverIterate
if (err) logAdd("Server failed to start!");
+
#include "nodalHusk.c" // Build initial nodal environment
  
// Parses a message content and responds to client
 
void processMessage(char* msg) {
 
  
// Create a new context node
+
if (err == 0) {
 
+
char *msg = malloc(100);
// validate and extract event, params and mime-type
+
sprintf(msg,"Daemon \"%s\" started successfully and serving on port %d.",peer,port);
//    /GET\s+\/+(.*?)(\/(.+))?\s+(HTTP\/[0-9.]+)/
+
logAdd(msg);
 
+
free(msg);
// add appropriate response to nodal context
 
// - restart, click?x&y, else content/mime/type
 
 
 
}
 
 
 
 
 
// Function called by each stream-node in network's reduction loop
 
// - there is also a streams-container node containing zero or more stream nodes
 
void server() {
 
FD_ZERO(fdset);
 
FD_SET(sock,fdset);
 
to.tv_sec = to.tv_usec = DELAY;
 
if (select(sock+1, fdset, NULL, NULL, &to)>0) {
 
// New connection request, accpet and create new stream-node
 
int fd = nonblocking(accept(sock, NULL, NULL));
 
if (fd>0) {
 
streamInfo *newsi = malloc(sizeof(streamInfo));
 
newsi->fd = fd;
 
newsi->inbuf = malloc(BUFSIZE);
 
newsi->outbuf = malloc(BUFSIZE);
 
newsi->inptr = 0;
 
newsi->outptr = 0;
 
//nodeSetState(newNode = add-me-to-stream-loop, STREAMINFO, newsi);
 
}
 
else logErr("accept(): failed!");
 
 
}
 
}
}
 
  
 
+
logAdd("Entering nodal reduction...\n");
// Each of the stream nodes points to this function in its State
+
while(nodeReduce(this=ROOT));
void client() {
+
free(space);
 
+
SDL_Quit();
// Get the info for this stream ready for reading/writing a packet if necessary
 
streamInfo *info = nodeGetState(this, STREAMINFO);
 
int i,fd = info->fd, inptr = info->inptr, outptr = info->outptr;
 
char *inbuf = info->inbuf, *outbuf = info->outbuf;
 
 
 
// Data to receive?
 
FD_ZERO(fdset);
 
FD_SET(fd,fdset);
 
to.tv_sec = to.tv_usec = DELAY;
 
if (select(fd+1, fdset, NULL, NULL, &to)>0) {
 
// read a packet into inbuf
 
if (i = recv(fd, inbuf+inptr, PAKSIZE, 0)>0) {
 
 
 
// test if complete message in buffer
 
char *message = NULL;
 
while (i--) {
 
//  /\r?\n\r?\n\x00?/
 
}
 
 
 
if (message) {
 
//inptr = info->inptr -= msg_size;
 
// hook a process into the loop
 
}
 
}
 
else if (i == 0) {
 
// zero bytes to read, do orderly termination
 
// todo: remove this stream node from loop
 
free(info);
 
}
 
else logErr("recv(): failed!");
 
}
 
 
 
// Data to send?
 
FD_ZERO(fdset);
 
FD_SET(fd,fdset);
 
to.tv_sec = to.tv_usec = DELAY;
 
if (select(fd+1, NULL, fdset, NULL, &to)>0) {
 
// write a packet from outbuf
 
int len = PAKSIZE; // or less
 
if (send(fd, outbuf+outptr, len, 0) == -1) logErr("send() failed!");
 
}
 
  
 
}
 
}

Revision as of 10:00, 25 July 2006

// This article and all its includes are licenced under LGPL // GPL: http://www.gnu.org/copyleft/lesser.html // SRC: http://www.organicdesign.co.nz/husk.c

  1. include <unistd.h>
  2. include <stdlib.h>
  3. include <stdio.h>
  4. include <string.h>
  5. include "SDL/SDL.h"
  6. include "SDL/SDL_image.h"
  7. if __WIN32__
  8. include <winsock2.h>
  9. else
  10. include <sys/socket.h>
  11. include <sys/select.h>
  12. include <netinet/in.h>
  13. include <sys/time.h> // for select()
  14. include <fcntl.h> // O_RDWR, O_NONBLOCK, F_GETFL, F_SETFL
  15. endif

// Globals int port = 8000; int err = 0; int this = 0; char *peer = "test"; // int main(int argc, char **argv) {

#include "util.c" // General utils, file,log,string etc

#if __WIN32__ // Set up as a daemon or service #include "servicate.c" #elif __UNIX__ #include "daemonise.c" #endif

#include "listSpace.c" // listSpace and some C-specific extras: hash, trie, linked-list #include "args.c" // Handle command-line args and globals like peer and port #include "nodeSpace.c" // NodeSpace function declarations and initialisation #include "serialise.c" // Nodal-to-text and visa-versa #include "interface.c" // Layer model (currently bitmap/imagemap-based) #include "server.c" // Set up listening socket and declare serverIterate #include "nodalHusk.c" // Build initial nodal environment


if (err == 0) { char *msg = malloc(100); sprintf(msg,"Daemon \"%s\" started successfully and serving on port %d.",peer,port); logAdd(msg); free(msg); }

logAdd("Entering nodal reduction...\n"); while(nodeReduce(this=ROOT)); free(space); SDL_Quit();

}