rendered paste body#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/time.h>
#include <string.h>
struct chatxstructure {
fd_set master;
fd_set read_fds;
int fdmax;
int listener;
int newfd;
}control;
struct chatxvars {
int nbytes;
int yes;
int addrlen;
int i;
int j;
int PORT;
int y;
int z;
}*vars;
void init();
void informserver(int fd,char *tempbuf,int nbytes);
int main(int argc,char *argv[])
{
extern struct chatxstructure control;
extern struct chatxvars *vars;
struct sockaddr_in myaddr;
struct sockaddr_in remoteaddr;
char *buf;
char *mesg;
if(argc != 2) {
fprintf(stderr,"usage : %s -> port \a\n",argv[0]);
return -1;
}
vars=(struct chatxvars*)malloc(sizeof(struct chatxvars));
buf=(char *)malloc(256);
init();
vars->PORT=atoi(argv[1]);
FD_ZERO(&control.master);
FD_ZERO(&control.read_fds);
// get the control.listener
if((control.listener = socket(AF_INET,SOCK_STREAM,0))==-1) {
perror("socket");
return -1;
}
// lose the pesky "address already in use" error message
if(setsockopt(control.listener,SOL_SOCKET,SO_REUSEADDR,&vars->yes,sizeof(int))==-1) {
perror("setsockopt");
return -1;
}
myaddr.sin_family=AF_INET;
myaddr.sin_addr.s_addr=htonl(INADDR_ANY);
myaddr.sin_port=htons(vars->PORT);
memset(&(myaddr.sin_zero),'\0',8);
if(bind(control.listener,(struct sockaddr *)&myaddr,sizeof(myaddr))==-1) {
perror("bind");
return -1;
}
if(listen(control.listener,10)==-1) {
perror("listen");
return -1;
}
// add the control.listener to the control.control.master set
FD_SET(control.listener,&control.master);
control.fdmax=control.listener;
// mail loop
mesg=(char *)malloc(128);
for(;;) {
control.read_fds=control.master; // copy it
if(select(control.fdmax+1,&control.read_fds,NULL,NULL,NULL)==-1) {
perror("select");
return -1;
}
for(vars->i=0;vars->i<=control.fdmax;vars->i++) {
if(FD_ISSET(vars->i,&control.read_fds)) { // we got one!!
if(vars->i==control.listener) {
vars->addrlen=sizeof(remoteaddr);
if((control.newfd=accept(control.listener,(struct sockaddr *)&remoteaddr,
&vars->addrlen))==-1) {
perror("accept");
}
else {
FD_SET(control.newfd,&control.master); // add to control.master set
if(control.newfd > control.fdmax) { // keep track of the maximum
control.fdmax=control.newfd;
}
printf("selectserver : new connection from %s on "
"socket %d\n",inet_ntoa(remoteaddr.sin_addr),control.newfd);
if(vars->y!=0) {
sprintf(mesg,"\nuser from %s signed in!\n",
inet_ntoa(remoteaddr.sin_addr));
for(vars->z=0;vars->z<=control.fdmax;vars->z++)
{
if(FD_ISSET(vars->z,&control.master))
if(vars->z!=control.listener && vars->z!= control.newfd)
if(send(vars->z,mesg,strlen(mesg),0)==-1)
perror("send");
}
}
vars->y++;
}
} else {
if((vars->nbytes=recv(vars->i,buf,sizeof(buf),0))<=0) {
if(vars->nbytes==0) {
//connection closed
printf("selectserver : socket %d hung up\n",vars->i);
sprintf(mesg,"\nuser from %s signed out!\n",
inet_ntoa(remoteaddr.sin_addr));
vars->y--;
for(vars->z=0;vars->z<=control.fdmax;vars->z++)
{
if(FD_ISSET(vars->z,&control.master))
if(vars->z!=control.listener && vars->z != vars->i)
if(send(vars->z,mesg,strlen(mesg),0)==-1)
perror("send");
}
}else {
perror("recv");
}
//control.newfd,
close(vars->i); // bye!
FD_CLR(vars->i,&control.master); // remove from control.master set
} else {
if( (vars->y)>1 ) {
//we got some data from a client
informserver(vars->i,buf,vars->nbytes);
for(vars->j=0;vars->j<=control.fdmax;vars->j++) {
if(FD_ISSET(vars->i,&control.master)) {
//except the control.listener and ourselves
if(vars->j!=control.listener && vars->j != vars->i) {
if(send(vars->j,buf,vars->nbytes,0)==-1) {
perror("send");
}
}
}
}
}
else {
sprintf(mesg,"server-client[%s]socket=%d : room's empty!\n",
inet_ntoa(remoteaddr.sin_addr),vars->i);
if(send(vars->i,mesg,strlen(mesg),0)==-1) {
perror("send");
}
}
}
}
}
}
} return 0;
}
void init()
{
extern struct chatxvars *var;
vars->yes=1;
vars->PORT=0;
vars->y=0;
vars->z=0;
}
void informserver(int fd,char *tempbuf,int nbytes)
{
tempbuf[nbytes]='\0';
fprintf(stdout,"data transimission from client on socket %d\n",fd);
fprintf(stdout,"data=%s\n",tempbuf);
}