⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 talksrvr.c

📁 Porting the Simple Sockets Library Dr. Charles E. Campbell, Jr.
💻 C
字号:
/* hw2-s.c: this program implements the homework #2 server *          I note that I cheated and used double-linked lists *          instead of a simple array of 5, but I hope that *          you may find that helpful, too. * *          The server here also acts as a pass-through: all *          other clients get told what any client said. * *   Author: Dr Charles E Campbell, Jr * *               Protocol * *   server->client *   m#...message      message from    #>0: client-id  #==0: server *   q                 tell client to quit * *   client->server *   m...message       message from client *   q                 client is quitting *   Q                 client tells server to quit */#include <stdio.h>#include <ctype.h>#include "xtdio.h"#include "sockets.h"/* ------------------------------------------------------------------------ * Definitions: */#define BUFSIZE	256#define SERVER	"HW2"#define PROMPT	"Server: "/* ------------------------------------------------------------------------ * Typedefs: */typedef struct Accept_str Accept;/* ------------------------------------------------------------------------ * Local Data Structures: */struct Accept_str {	int     id;	Socket *skt;	Accept *nxt;	Accept *prv;	};/* ------------------------------------------------------------------------ * Global Data: */Accept *ahd= NULL;		/* accept socket list head */Accept *atl= NULL;		/* accept socket list tail *//* ------------------------------------------------------------------------ * Explanation: *//* ------------------------------------------------------------------------ * Prototypes: */int main( int, char **);          /* hw2-s.c */void RemoveAccpt(Accept *);       /* hw2-s.c */void SendAllbut(Accept *,char *); /* hw2-s.c *//* ------------------------------------------------------------------------ * Source Code: *//* main: */int main(  int    argc,  char **argv){Accept     *accpt   = NULL;Accept     *accptnxt= NULL;Socket     *srvr    = NULL;char        buf[BUFSIZE];int         didwork = 1;int         doquit  = 0;int         result;static int  id      = 0;rdcolor();/* attempt to open server */srvr= Sopen(SERVER,"S");/* this probably happens only when the PortMaster isn't up */if(!srvr) error(XTDIO_ERROR,"unable to open <%s%s%s> server\n",YELLOW,SERVER,GREEN);Smaskset(srvr);                     /* enter server into mask */Smaskfdset(fileno(stdin));          /* enter stdin  into mask */fputs(PROMPT,stdout);               /* print out prompt       */fflush(stdout);                     /* force stdout out       */while(!doquit && didwork) {	result  = Smaskwait();	didwork = 0;	if(result > 0) {                /* if error, returns -1   */		if(Stest(srvr) > 0) {       /* if error, returns -1   */			Socket *skt;			didwork = 1;		/* only indicate didwork when something was done */			/* accept a new Socket */			skt= Saccept(srvr);			if(!skt) {				error(XTDIO_WARNING,"server tested having data but unable to accept!\n");				break;				}			Smaskset(skt);			/* allocate and doubly-link in new Accept */			accpt= (Accept *) malloc(sizeof(Accept));			if(atl) atl->nxt= accpt;			else    ahd     = accpt;			accpt->prv= atl;			accpt->nxt= NULL;			atl       = accpt;			/* initialize */			accpt->skt= skt;			accpt->id = ++id;			Smaskset(accpt->skt);			}		else {			/* check out all accepted clients for any work to do */			for(accpt= ahd, accptnxt= NULL; accpt && !doquit; accpt= accptnxt) {				accptnxt= accpt->nxt;		/* note that RemoveAccpt may delete this accpt! */				if(accpt->skt) {					result  = Stest(accpt->skt);					if(result > 0) {						if(Sgets(buf,BUFSIZE,accpt->skt)) {							char   *b;							Accept *snd;							int     fromid;							didwork = 1;		/* only indicate didwork when something was done */							/* translate command from client */							switch(buf[0]) {							case 'q':	/* client is quitting  */								RemoveAccpt(accpt);								break;							case 'Q':	/* client told server to quit */								doquit= 1;								RemoveAccpt(accpt);								break;							case 'm':	/* message from client */								for(b= buf+1; *b && isspace(*b); ++b) ; /* skip "m ..."   */								printf("\nclient#%d: %s\n",accpt->id,b);								SendAllbut(accpt,b);  /* send message to all other clients */								fputs(PROMPT,stdout); /* print out prompt                  */								fflush(stdout);       /* force stdout out                  */								break;								}							}						else RemoveAccpt(accpt);						}					else if(result < 0) RemoveAccpt(accpt);					}				}			}		/* ok, didn't do anything with Sockets, so must be stdin */		if(!didwork) {			didwork= 1;			fgets(buf,BUFSIZE,stdin);        /* get string from stdin       */			srmtrblk(buf);                   /* remove trailing whitespace  */			if(!strcmp(buf,"QUIT")) {        /* user command server to QUIT */				break;				}			SendAllbut((Accept *) NULL,buf); /* send to ALL accept Sockets  */			fputs(PROMPT,stdout);            /* print out prompt            */			fflush(stdout);                  /* force stdout out            */			}		}	else break;	}/* close everything down */while(ahd) RemoveAccpt(ahd);Sclose(srvr);return 0;}/* --------------------------------------------------------------------- *//* RemoveAccpt: this function removes given Accept* from linked list */void RemoveAccpt(Accept *accpt){/* sanity check */if(!accpt || !accpt->skt) {	error(XTDIO_SEVERE,"RemoveAccpt told to remove %s!\n",	  accpt? "accpt with null socket" : "null accpt");	}/* tell client to quit */Sputs("q",accpt->skt);/* de-link */if(accpt->prv) accpt->prv->nxt= accpt->nxt;else           ahd            = accpt->nxt;if(accpt->nxt) accpt->nxt->prv= accpt->prv;else           atl            = accpt->prv;Smaskunset(accpt->skt); /* remove from mask */Sclose(accpt->skt);     /* close socket     */free((char *) accpt);   /* delete Accept    */}/* --------------------------------------------------------------------- *//* SendAllbut: this function sends a message to all clients except the * one on the argument list */void SendAllbut(Accept *notme,char *msg){Accept *accpt;for(accpt= ahd; accpt; accpt= accpt->nxt) if(accpt != notme) {	Sprintf(accpt->skt,"m%d %s",notme? notme->id : 0,msg);	}}/* --------------------------------------------------------------------- */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -