Difference between revisions of "Server.c"
(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 | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
int processMessage(char* msg); | int processMessage(char* msg); | ||
| − | int | + | int server, sockopt_on = 1; |
struct sockaddr_in my_addr, client_addr; | struct sockaddr_in my_addr, client_addr; | ||
| − | |||
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 (( | + | 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( | + | 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( | + | 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( | + | 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) { | ||
| − | // | + | |
| − | if (stream = accept( | + | // 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)); | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
// 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
- 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 // Includes for socket (trying to use one source cpp for osx,win32,*ux)
- ifdef WINDOWS
- include <winsock.h>
- else
- include <sys/socket.h>
- include <netinet/in.h>
- include <fcntl.h>
//#include <arpa/inet.h> //#include <netdb.h> //#include <unistd.h>
- 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"); }



