Difference between revisions of "Server.c"

From Organic Design wiki
(initialise some vars)
(bit more done - not ready to compile yet)
Line 1: Line 1:
 +
// good sock function ref at
 +
// http://www.opengroup.org/onlinepubs/009695399/idx/networking.html
 +
 +
// Set up socket and listening loop
 +
#define LISTENPORT 2012
 +
#define BACKLOG 10
 +
#define BUFSIZE 128 // keeping buf small for handling many connections without fork
 +
#define MAXCLIENTS 100
 +
#define MSG "stink ow!"
 +
 
// - todo: don't exit on connect errors, keep trying every 10s
 
// - todo: don't exit on connect errors, keep trying every 10s
 
// Includes for socket (trying to use one source cpp for osx,win32,*ux)
 
// Includes for socket (trying to use one source cpp for osx,win32,*ux)
Line 6: Line 16:
 
#include <sys/socket.h>
 
#include <sys/socket.h>
 
#include <netinet/in.h>
 
#include <netinet/in.h>
 +
#include <fcntl.h>
 
//#include <arpa/inet.h>
 
//#include <arpa/inet.h>
 
//#include <netdb.h>
 
//#include <netdb.h>
 
//#include <unistd.h>
 
//#include <unistd.h>
 
#endif
 
#endif
 
// Set up socket and listening loop
 
#define LISTENPORT 2012
 
#define BACKLOG 10
 
#define BUFSIZE 128 // keeping buf small for handling many connections without fork
 
#define MSG "stink ow!"
 
  
 
int processMessage(char* msg);
 
int processMessage(char* msg);
int sock, conn;
+
int server, sockopt_on = 1;
 
struct sockaddr_in my_addr, client_addr;
 
struct sockaddr_in my_addr, client_addr;
int sockopt_on = 1;
 
 
int sa_in_size = sizeof(struct sockaddr_in);
 
int sa_in_size = sizeof(struct sockaddr_in);
 
char response[80];
 
char response[80];
  
 
// get a socket
 
// get a socket
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+
if ((server = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
 
perror("socket");
 
perror("socket");
 
exit(1);
 
exit(1);
 
}
 
}
 +
 +
// make it non-blocking so accept() returns straight away with EAGAIN or EWOULDBLOCK
 +
fcntl(server, O_NONBLOCK);
  
 
// make it reusable
 
// make it reusable
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &sockopt_on, sizeof(int)) < 0) {
+
if (setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &sockopt_on, sizeof(int)) < 0) {
 
perror("setsockopt");
 
perror("setsockopt");
 
exit(1);
 
exit(1);
Line 37: Line 44:
  
 
// first zero the struct
 
// first zero the struct
memset((char *) &my_addr, 0, sa_in_size);
+
memset((char *)&my_addr, 0, sa_in_size);
  
 
// now fill in the fields we need
 
// now fill in the fields we need
Line 45: Line 52:
  
 
// bind our socket to the port
 
// bind our socket to the port
if (bind(sock, (struct sockaddr *)&my_addr, sa_in_size) < 0) {
+
if (bind(server, (struct sockaddr *)&my_addr, sa_in_size) < 0) {
 
perror("bind");
 
perror("bind");
 
exit(1);
 
exit(1);
Line 51: Line 58:
  
 
// start listening for incoming connections
 
// start listening for incoming connections
if (listen(sock, BACKLOG) < 0) {
+
if (listen(server, BACKLOG) < 0) {
 
perror("listen");
 
perror("listen");
 
exit(1);
 
exit(1);
 
}
 
}
 +
 +
// struct to represent a currently connected stream
 +
typedef struct streamstruct {
 +
char* buf;
 +
int fileno;
 +
} streamInfo;
 +
 +
// array of current client connections
 +
streamInfo* streams[MAXCLIENTS];
 +
nStreams = 0;
  
 
// Need an input buffer for each stream
 
// Need an input buffer for each stream
 
char *buf = malloc(BUFSIZE);
 
char *buf = malloc(BUFSIZE);
int stream, bufsize;
+
int i, stream, bufsize;
  
 
while(1) {
 
while(1) {
// grab connections
+
 
if (stream = accept(sock, (struct sockaddr *)&client_addr, &sa_in_size) < 0) {
+
// Wait for any incomming connection
 +
// O_NONBLOCK is set so, EAGAIN or EWOULDBLOCK returned if no requests
 +
if (stream = accept(server, (struct sockaddr *)&client_addr, &sa_in_size) < 0) {
 
perror("accept");
 
perror("accept");
 
exit(1);
 
exit(1);
 +
}
 +
 +
// loop thru streams and read a packet from any with data to read
 +
for (i = 0; i < nStreams; i++) {
 +
 
}
 
}
  
Line 70: Line 94:
 
// - should get info for this stream, incl buf
 
// - should get info for this stream, incl buf
 
printf("got connection from %s\n", inet_ntoa(client_addr.sin_addr));
 
printf("got connection from %s\n", inet_ntoa(client_addr.sin_addr));
 
// send a greeting - should do this in response
 
if (send(stream, MSG, strlen(MSG)+1, 0) == -1) {
 
perror("send");
 
}
 
else printf("Sent message MSG\n");
 
  
 
// get the reply
 
// get the reply
Line 89: Line 107:
 
int processMessage(char* msg) {
 
int processMessage(char* msg) {
 
// test if restart cmd first
 
// test if restart cmd first
 +
 +
// send response
 +
if (send(stream, MSG, strlen(MSG)+1, 0) == -1) {
 +
perror("send");
 +
}
 +
else printf("Sent message MSG\n");
 
}
 
}

Revision as of 01:10, 3 July 2006

// good sock function ref at // http://www.opengroup.org/onlinepubs/009695399/idx/networking.html

// Set up socket and listening loop

  1. define LISTENPORT 2012
  2. define BACKLOG 10
  3. define BUFSIZE 128 // keeping buf small for handling many connections without fork
  4. define MAXCLIENTS 100
  5. define MSG "stink ow!"

// - todo: don't exit on connect errors, keep trying every 10s // Includes for socket (trying to use one source cpp for osx,win32,*ux)

  1. ifdef WINDOWS
  2. include <winsock.h>
  3. else
  4. include <sys/socket.h>
  5. include <netinet/in.h>
  6. include <fcntl.h>

//#include <arpa/inet.h> //#include <netdb.h> //#include <unistd.h>

  1. endif

int processMessage(char* msg); int server, sockopt_on = 1; struct sockaddr_in my_addr, client_addr; int sa_in_size = sizeof(struct sockaddr_in); char response[80];

// get a socket if ((server = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { perror("socket"); exit(1); }

// make it non-blocking so accept() returns straight away with EAGAIN or EWOULDBLOCK fcntl(server, O_NONBLOCK);

// make it reusable if (setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &sockopt_on, sizeof(int)) < 0) { perror("setsockopt"); exit(1); }

// first zero the struct memset((char *)&my_addr, 0, sa_in_size);

// now fill in the fields we need my_addr.sin_family = PF_INET; my_addr.sin_port = htons(LISTENPORT); my_addr.sin_addr.s_addr = htonl(INADDR_ANY);

// bind our socket to the port if (bind(server, (struct sockaddr *)&my_addr, sa_in_size) < 0) { perror("bind"); exit(1); }

// start listening for incoming connections if (listen(server, BACKLOG) < 0) { perror("listen"); exit(1); }

// struct to represent a currently connected stream typedef struct streamstruct { char* buf; int fileno; } streamInfo;

// array of current client connections streamInfo* streams[MAXCLIENTS]; nStreams = 0;

// Need an input buffer for each stream char *buf = malloc(BUFSIZE); int i, stream, bufsize;

while(1) {

// Wait for any incomming connection // O_NONBLOCK is set so, EAGAIN or EWOULDBLOCK returned if no requests if (stream = accept(server, (struct sockaddr *)&client_addr, &sa_in_size) < 0) { perror("accept"); exit(1); }

// loop thru streams and read a packet from any with data to read for (i = 0; i < nStreams; i++) {

}

// log the connecter // - should get info for this stream, incl buf printf("got connection from %s\n", inet_ntoa(client_addr.sin_addr));

// get the reply // - should keep receiving until \r\n\0?, then call serverProcessMessage() if (recv(stream, buf, bufsize, 0) == -1) perror("recv"); else printf("The client says \"%s\"\n", buf);

close(stream); // should close when no more data on this stream (somehow)

}

// Parses a message content and responds to client int processMessage(char* msg) { // test if restart cmd first

// send response if (send(stream, MSG, strlen(MSG)+1, 0) == -1) { perror("send"); } else printf("Sent message MSG\n"); }