Code:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <stdio.h>
#include <unistd.h> //For read() and write()
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MSG_SIZE 80
#define MAX_CLIENTS 100
#define MYPORT 7400
void exitClient(int fd, fd_set *readfds, char fd_array[],
int *num_clients)
{
int i;
close(fd);
FD_CLR(fd, readfds); //clear the leaving client from the set
for (i = 0; i < (*num_clients) - 1; i++)
{
if (fd_array[i] == fd)
{
break;
}
}
for (; i < (*num_clients) - 1; i++)
{
(fd_array[i]) = (fd_array[i + 1]);
}
(*num_clients)--;
}
int main(int argc, char *argv[])
{
int i=0;
int port1, port2;
int num_clients1 = 0, num_clients2 = 0;
int server_sockfd1,server_sockfd2, client_sockfd1, client_sockfd2;
struct sockaddr_in chatroom1, chatroom2;
int addresslen = sizeof(struct sockaddr_in);
struct sockaddr_storage their_addr1, their_addr2;
socklen_t addr_size1, addr_size2;
int fd;
char fd_array1[MAX_CLIENTS], fd_array2[MAX_CLIENTS];
fd_set readfds1, readfds2, testfds1, testfds2, clientfds, readfds;
char msg[MSG_SIZE + 1];
char kybd_msg[MSG_SIZE + 10];
int result;
int allowed; //for firewall
int choice; //for switch
int auth; //to check validity of password
char *viewclient_addr1, *viewclient_addr2; //for displaying address of connecting client
time_t now;
struct tm *tm;
if(argc== 1 || argc == 4)
{
if(argc==4)
{
if(strcmp("-p",argv[1])==0)
{
sscanf(argv[2],"%i",&port1);
sscanf(argv[3],"%i",&port2);
}
else
{
printf("Invalid parameters. Use: ./server [-p] [PORT1] [PORT2]\n");
exit(0);
}
}
else if(argc==1)
{
port1=MYPORT;
port2=MYPORT+1;
}
printf("\n**SERVER APPLET**\n\n");
printf("Recognised commands : \n");
printf("-type -|quit|- anytime to close the server.\n");
fflush(stdout);
/* Create and name a socket for the server */
server_sockfd1 = socket(AF_INET, SOCK_STREAM, 0);
chatroom1.sin_family = AF_INET;
chatroom1.sin_addr.s_addr = htonl(INADDR_ANY); // inet_addr("127.0.0.1");
chatroom1.sin_port = htons(port1);
bind(server_sockfd1, (struct sockaddr *)&chatroom1, addresslen);
server_sockfd2 = socket(AF_INET, SOCK_STREAM, 0);
chatroom2.sin_family = AF_INET;
chatroom2.sin_addr.s_addr = htonl(INADDR_ANY); // inet_addr("127.0.0.1");
chatroom2.sin_port = htons(port2);
bind(server_sockfd2, (struct sockaddr *)&chatroom2, addresslen);
/* Create a connection queue and initialize a file descriptor set */
listen(server_sockfd1, 1);
listen(server_sockfd2, 1);
FD_ZERO(&readfds1);
FD_ZERO(&readfds2);
FD_SET(server_sockfd1, &readfds1);
FD_SET(server_sockfd2, &readfds2);
FD_SET(0, &readfds1); /* Add keyboard to file descriptor set */
FD_SET(0, &readfds2); /* Add keyboard to file descriptor set */
/* Now wait for clients and requests */
while (1)
{
testfds1 = readfds1;
select(FD_SETSIZE, &testfds1, NULL, NULL, NULL);
testfds2 = readfds2;
select(FD_SETSIZE, &testfds2, NULL, NULL, NULL);
/* If there is activity, find which descriptor it's on using FD_ISSET */
for (fd = 0; fd < FD_SETSIZE; fd++)
{
if (FD_ISSET(fd, &testfds1)||FD_ISSET(fd, &testfds2))
{
if (fd == server_sockfd1)
{ /* Accept a new connection request */
addr_size1 = sizeof their_addr1;
client_sockfd1 = accept(server_sockfd1, (struct sockaddr *)&their_addr1, &addr_size1);
/* Displays incoming client IP address */
viewclient_addr1 = inet_ntoa(their_addr1);
printf("Receiving incoming connection from IP address %s on port %d.\n\n",viewclient_addr1,port1);
fflush(stdout);
if (num_clients1 < MAX_CLIENTS)
{
FD_SET(client_sockfd1, &readfds1);
fd_array1[num_clients1]=client_sockfd1;
/*Client ID*/
now=time(NULL);
tm=localtime(&now);
printf("Client %d joined at %d:%d. \n\n",++num_clients1,tm->tm_hour,tm->tm_min);
fflush(stdout);
sprintf(msg,"M%2d",client_sockfd1);
/*write 2 byte clientID */
send(client_sockfd1,msg,strlen(msg),0);
}
else
{
sprintf(msg, "XSorry, too many clients. Try again later.\n");
write(client_sockfd1, msg, strlen(msg));
close(client_sockfd1);
}
}
if (fd == server_sockfd2)
{ /* Accept a new connection request */
addr_size2 = sizeof their_addr2;
client_sockfd2 = accept(server_sockfd2, (struct sockaddr *)&their_addr2, &addr_size2);
/* Displays incoming client IP address */
viewclient_addr2 = inet_ntoa(their_addr2);
printf("Receiving incoming connection from IP address %s on port %d.\n\n",viewclient_addr2,port2);
fflush(stdout);
if (num_clients1 < MAX_CLIENTS)
{
FD_SET(client_sockfd2, &readfds2);
fd_array2[num_clients2]=client_sockfd2;
/*Client ID*/
now=time(NULL);
tm=localtime(&now);
printf("Client %d joined at %d:%d. \n\n",++num_clients2,tm->tm_hour,tm->tm_min);
fflush(stdout);
sprintf(msg,"M%2d",client_sockfd2);
/*write 2 byte clientID */
send(client_sockfd2,msg,strlen(msg),0);
}
else
{
sprintf(msg, "XSorry, too many clients. Try again later.\n");
write(client_sockfd2, msg, strlen(msg));
close(client_sockfd2);
}
}
else if (fd == 0)
{ /* Process keyboard activity */
fgets(kybd_msg, MSG_SIZE + 1, stdin);
if (strcmp(kybd_msg, "quit\n")==0)
{
sprintf(msg, "XServer is shutting down.\n");
for (i = 0; i < num_clients1 ; i++)
{
write(fd_array1[i], msg, strlen(msg));
close(fd_array1[i]);
}
for (i = 0; i < num_clients2 ; i++)
{
write(fd_array2[i], msg, strlen(msg));
close(fd_array2[i]);
}
close(server_sockfd1);
close(server_sockfd2);
exit(0);
}
else
{
sprintf(msg, "MServer : %s", kybd_msg);
for (i = 0; i < num_clients1 ; i++)
{
write(fd_array1[i], msg, strlen(msg));
}
for (i = 0; i < num_clients2 ; i++)
{
write(fd_array2[i], msg, strlen(msg));
}
}
}
else if(FD_ISSET(fd, &testfds1)||FD_ISSET(fd,&testfds2))
{ /*Process Client specific activity*/
//read data from open socket
result = read(fd, msg, MSG_SIZE);
if(result==-1)
{
perror("read()");
}
else if(result>0)
{
/*read 2 bytes client id*/
sprintf(kybd_msg,"MClient %d : ",fd);
fflush(stdout);
msg[result]='\0';
/*concatenate the client id with the client's message*/
strcat(kybd_msg,msg+1);
/*print to other clients*/
if(FD_ISSET(fd, &testfds1))
{
for(i=0;i<num_clients1;i++)
{
if (fd_array1[i]!= fd) /*dont write msg to same client*/
write(fd_array1[i],kybd_msg,strlen(kybd_msg));
}
}
if(FD_ISSET(fd, &testfds2))
{
for(i=0;i<num_clients2;i++)
{
if (fd_array2[i]!= fd) /*dont write msg to same client*/
write(fd_array2[i],kybd_msg,strlen(kybd_msg));
}
}
/*print to server*/
now=time(NULL);
tm=localtime(&now);
printf("%d:%d : %s",tm->tm_hour,tm->tm_min,kybd_msg+1);
fflush(stdout);
/*Exit Client*/
if(msg[0] == 'X')
{
exitClient(fd,&readfds1, fd_array1,&num_clients1);
}
}
}
else if(!FD_ISSET(fd, &testfds1) && !FD_ISSET(fd, &testfds2))
{
/* A client is leaving */
exitClient(fd,&readfds1, fd_array1,&num_clients1);
exitClient(fd,&readfds2, fd_array2,&num_clients2);
}//if
}//if
}//for
}//while
}//argc if
else
{
printf("Invalid parameters. Use: ./server [-p] [PORT1] [PORT2]\n");
exit(0);
}
}//main