/*************************************************************************** chatv2.c ------------------- begin : Fri Mar 21 01:05:09 CST 2003 copyright : (C) 2003 by Andy Ruder email : aeruder@yahoo.com ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include #include /* Non-network stuff */ #include #include #include struct Server { int socket; struct sockaddr_in serverAddress; }; struct Connection; struct Connection { int socket; struct sockaddr_in connectionAddress; int sockaddrLength; char readBuffer[1024]; struct Connection *next; }; struct Connection *headConnection = NULL; void removeConnection(struct Connection *connection) { struct Connection *current = headConnection; if (current == connection) { headConnection = headConnection->next; } while(current) { if (connection == current->next) { current->next = connection->next; break; } current = current->next; } } void addConnection(struct Connection *connection) { connection->next = headConnection; headConnection = connection; } int findMaxSocketNumber(int serverSocket) { int x = -1; struct Connection *current; for (current = headConnection; current != NULL; current = current->next) { if (current->socket > x) { x = current->socket; } } if (serverSocket > x) { x = serverSocket; } return x; } int main(void) // main should ALWAYS return int { struct Server myServer; struct Connection *connection; fd_set readSet; int maxSocket; if ((myServer.socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("Problem calling socket()"); return 1; } myServer.serverAddress.sin_family = AF_INET; myServer.serverAddress.sin_port = htons(4000); myServer.serverAddress.sin_addr.s_addr = INADDR_ANY; memset(&(myServer.serverAddress.sin_zero), '\0', 8); if ( bind(myServer.socket, (struct sockaddr *)&myServer.serverAddress, sizeof(struct sockaddr)) == -1) { perror("Problem calling bind()"); close(myServer.socket); return 2; } if (listen(myServer.socket, 5) == -1) { perror("Problem calling listen()"); close(myServer.socket); return 3; } maxSocket = myServer.socket; while(1) { FD_ZERO(&readSet); FD_SET(myServer.socket, &readSet); for (connection = headConnection; connection != NULL; connection = connection->next) { FD_SET(connection->socket, &readSet); } select(maxSocket + 1, &readSet, NULL, NULL, NULL); if (FD_ISSET(myServer.socket, &readSet)) { struct Connection *newConnection; newConnection = malloc(sizeof(struct Connection)); addConnection(newConnection); newConnection->sockaddrLength = sizeof(struct sockaddr); newConnection->socket = accept(myServer.socket, (struct sockaddr *) &(newConnection->connectionAddress), &(newConnection->sockaddrLength)); maxSocket = findMaxSocketNumber(myServer.socket); } for (connection = headConnection; connection != NULL;) { int bytesRead; struct Connection *current; if (!FD_ISSET(connection->socket, &readSet)) { connection = connection->next; continue; } bytesRead = read(connection->socket, connection->readBuffer, 1023); if (bytesRead == 0) { struct Connection *deadConnection; close(connection->socket); removeConnection(connection); maxSocket = findMaxSocketNumber(myServer.socket); deadConnection = connection; connection = connection->next; free(deadConnection); continue; } for (current = headConnection; current != NULL; current = current->next) { if (current != connection) { write(current->socket, connection->readBuffer, bytesRead); } } connection = connection->next; } } return 0; }