All pastes #329763 Raw Edit

Miscellany

public text v1 · immutable
#329763 ·published 2007-01-27 01:01 UTC
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);
}