Автор |
Сообщение |
Insomni
[1.6]
|
0
Клиент - серверное приложение на Си
Помогите плиз допилить код, вобщем нужно сделать чтобы сервер при получении сообщения отправлял его всем подключенным клиентам (исключая отправителя). Нужно сделать через массив или связанный список. сам сервер #include #include #include #include #include #include #include #include #include #include
#define NLISTEN 1024 #define server_name (argv[0])
/*----------------------------------------------------------------------------*/
void error(int status, int err, char* fmt, ...) { va_list ap; va_start(ap,fmt); vfprintf(stderr,fmt,ap); va_end(ap); if(err) fprintf(stderr, " error %d: %s\n",err,strerror(err)); if(status) exit(status); }
/*---------------------------------------------------------------------------*/
/* main function */ int main (int argc, char** argv) { /*Sockets*/ int srv_st = 0, clt_st = 0; struct sockaddr_in clt_addr, srv_addr; /*client and server addr's */ socklen_t sockaddrsize = sizeof(struct sockaddr_in);
char *host = 0, *sport = 0; fd_set master; /* master file descriptor list */ fd_set read_fds; /* temp fd list for select() */
int fdmax = 0; /* need for keep max fd */ int res = 0; /* for returns values */ int i = 0, j = 0; /* iterators */
char buf[32768]; /* buffer for received data */ bzero (buf, 32768); /*clear buf*/
struct servent *sp; struct hostent *hp; char *endptr; short port; /* port number */
int op = 1; /* needed for sockopt */
/* parse command line */ if(argc != 2) printf("usage: %s \n", argv[0]), exit(0); else host = 0, sport = argv[1];
/* clear fd lists */ FD_ZERO(&master); FD_ZERO(&read_fds);
/* fill server address */ bzero ((void*)&srv_addr, sizeof(srv_addr)); /* fill zeroes */
srv_addr.sin_family = PF_INET; srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
/* fill port */ port = strtol( sport, &endptr, 0); if( *endptr == '\0' ) srv_addr.sin_port = htons(port); else { error(1,0,"unknown service: %s\n",sport); }
/* Create TCP based socket */ srv_st = socket(PF_INET, SOCK_STREAM, 0); if( srv_st < 0 ) error(1, errno, "error socket");
/* set SO_REUSEADDR option */ res = setsockopt(srv_st, SOL_SOCKET, SO_REUSEADDR, (const char*)&op,sizeof(op)); if(res) error(1, errno, "error setsockopt");
/* bind server socket to srv_addr */ res = bind(srv_st, (struct sockaddr*)&srv_addr, sockaddrsize); int pt = 50000; while (res) { if ( res < 0 ) { error(0, errno, "error bind, try again with port %d",pt); srv_addr.sin_port = htons(pt++); if ( pt >= 55000 ) error(1,0,"error bind, no enough ports in range"); res = bind(srv_st, (struct sockaddr*)&srv_addr, sockaddrsize); } else error(1, errno, "error bind"); }
/* create queue for clients requests */ res = listen(srv_st, NLISTEN); if(res == -1) error(1, errno, "listen");
/* add srv_st to master fd list */ FD_SET(srv_st, &master);
/* keep track of the biggest file descriptor */ fdmax = srv_st;
/* main loop */ for(;;) { read_fds = master; /* copy master list */
/* waiting new connection or data */ if (select( fdmax+1, &read_fds, NULL, NULL, NULL) == -1) { error(1, errno, "select"); }
/* run through the existing connections looking for data to read */ for( i=0; i<=fdmax; i++) { if(FD_ISSET(i, &read_fds)) /* we have got new data */ { if( i == srv_st ) { /* wait new connection */ clt_st = accept(srv_st, (struct sockaddr*)&clt_addr, &sockaddrsize); if( clt_st < 0) error(0, errno,"error accept"); else { FD_SET(clt_st, &master); /* add new socket to master */ if( clt_st > fdmax ) fdmax = clt_st; /* keep max descriptor */ } } else { /* got new data */ res = read(i, buf, sizeof(buf));
if( res <= 0) { /* client closed connection */ if( res == 0 ) { /* close socket and del i from master */ close(i); FD_CLR(i, &master); } } else { /* we have got a msg in buf from i client */ /* send message back */ printf ("recieved %d bytes\n",res); res = write(i, buf, res); if( res == -1 ) error(0,errno,"send"); printf ("sent %d bytes\n",res); } } } } } /* close srv_st socket */ close (srv_st); return 0; }
если есть готовый то вобще шикарно
|
01 фев 2012, 22:11 |
|
|
FlashFire
[1.1]
<Адский Кипиш>
Сервер: Свежеватель Душ
Рейтинг поля боя: 956
2х2: 2013
3х3: 1821
5х5: 1947
|
0
Клиент - серверное приложение на Си
Ты пришёл в нужное место, бро.
|
02 фев 2012, 04:06 |
|
|
Ph34rd
[0.1]
|
1
Клиент - серверное приложение на Си
Скрытый текст Код: #include #include #include #include #include #include #include #include #include #include
#define NLISTEN 1024 #define server_name (argv[0])
/*----------------------------------------------------------------------------*/
void error(int status, int err, char* fmt, ...) { va_list ap; va_start(ap,fmt); vfprintf(stderr,fmt,ap); va_end(ap); if(err) fprintf(stderr, " error %d: %s\n",err,strerror(err)); if(status) exit(status); }
/*---------------------------------------------------------------------------*/
/* main function */ int main (int argc, char** argv) { /*Sockets*/ int srv_st = 0, clt_st = 0; struct sockaddr_in clt_addr, srv_addr; /*client and server addr's */ socklen_t sockaddrsize = sizeof(struct sockaddr_in);
char *host = 0, *sport = 0; fd_set master; /* master file descriptor list */ fd_set read_fds; /* temp fd list for select() */
int fdmax = 0; /* need for keep max fd */ int res = 0; /* for returns values */ int i = 0, j = 0; /* iterators */
char buf[32768]; /* buffer for received data */ bzero (buf, 32768); /*clear buf*/
struct servent *sp; struct hostent *hp; char *endptr; short port; /* port number */
int op = 1; /* needed for sockopt */
/* parse command line */ if(argc != 2) printf("usage: %s \n", argv[0]), exit(0); else host = 0, sport = argv[1];
/* clear fd lists */ FD_ZERO(&master); FD_ZERO(&read_fds);
/* fill server address */ bzero ((void*)&srv_addr, sizeof(srv_addr)); /* fill zeroes */
srv_addr.sin_family = PF_INET; srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
/* fill port */ port = strtol( sport, &endptr, 0); if( *endptr == '\0' ) srv_addr.sin_port = htons(port); else { error(1,0,"unknown service: %s\n",sport); }
/* Create TCP based socket */ srv_st = socket(PF_INET, SOCK_STREAM, 0); if( srv_st < 0 ) error(1, errno, "error socket");
/* set SO_REUSEADDR option */ res = setsockopt(srv_st, SOL_SOCKET, SO_REUSEADDR, (const char*)&op,sizeof(op)); if(res) error(1, errno, "error setsockopt");
/* bind server socket to srv_addr */ res = bind(srv_st, (struct sockaddr*)&srv_addr, sockaddrsize); int pt = 50000; while (res) { if ( res < 0 ) { error(0, errno, "error bind, try again with port %d",pt); srv_addr.sin_port = htons(pt++); if ( pt >= 55000 ) error(1,0,"error bind, no enough ports in range"); res = bind(srv_st, (struct sockaddr*)&srv_addr, sockaddrsize); } else error(1, errno, "error bind"); }
/* create queue for clients requests */ res = listen(srv_st, NLISTEN); if(res == -1) error(1, errno, "listen");
/* add srv_st to master fd list */ FD_SET(srv_st, &master);
/* keep track of the biggest file descriptor */ fdmax = srv_st;
/* main loop */ for(;;) { read_fds = master; /* copy master list */
/* waiting new connection or data */ if (select( fdmax+1, &read_fds, NULL, NULL, NULL) == -1) { error(1, errno, "select"); }
/* run through the existing connections looking for data to read */ for( i=0; i<=fdmax; i++) { if(FD_ISSET(i, &read_fds)) /* we have got new data */ { if( i == srv_st ) { /* wait new connection */ clt_st = accept(srv_st, (struct sockaddr*)&clt_addr, &sockaddrsize); if( clt_st < 0) error(0, errno,"error accept"); else { FD_SET(clt_st, &master); /* add new socket to master */ if( clt_st > fdmax ) fdmax = clt_st; /* keep max descriptor */ } } else { /* got new data */ res = read(i, buf, sizeof(buf));
if( res <= 0) { /* client closed connection */ if( res == 0 ) { /* close socket and del i from master */ close(i); FD_CLR(i, &master); } } else { /* we have got a msg in buf from i client */ /* send message back */ printf ("recieved %d bytes\n",res); for(j = 0; j <=fdmax; j++) { if(FD_ISSET(j, &master)) { if((j != srv_st) && (j != i)) { res = write(j, buf, res); if( res == -1 ) error(0,errno,"send"); printf ("sent %d bytes to fd=%d\n",res,j); } } } } } } } } /* close srv_st socket */ close (srv_st); return 0; } и никаких дополнительных массивов и списков не нужно, в master хранятся все открытые дескрипторы... а так тут много чего нету, обработки всяких ошибок и тп (в частности если клиент отвалится по таймауту)... и вообще я бы смотрел в сторону libevent/libev и тп если нужен такой функционал...
|
02 фев 2012, 04:59 |
|
|
karakas
[-0.3]
|
0
Клиент - серверное приложение на Си
Фу, Си :(
|
02 фев 2012, 09:05 |
|
|
Insomni
[1.6]
|
0
Клиент - серверное приложение на Си
Ph34rd писал(а): Скрытый текст Код: #include #include #include #include #include #include #include #include #include #include
#define NLISTEN 1024 #define server_name (argv[0])
/*----------------------------------------------------------------------------*/
void error(int status, int err, char* fmt, ...) { va_list ap; va_start(ap,fmt); vfprintf(stderr,fmt,ap); va_end(ap); if(err) fprintf(stderr, " error %d: %s\n",err,strerror(err)); if(status) exit(status); }
/*---------------------------------------------------------------------------*/
/* main function */ int main (int argc, char** argv) { /*Sockets*/ int srv_st = 0, clt_st = 0; struct sockaddr_in clt_addr, srv_addr; /*client and server addr's */ socklen_t sockaddrsize = sizeof(struct sockaddr_in);
char *host = 0, *sport = 0; fd_set master; /* master file descriptor list */ fd_set read_fds; /* temp fd list for select() */
int fdmax = 0; /* need for keep max fd */ int res = 0; /* for returns values */ int i = 0, j = 0; /* iterators */
char buf[32768]; /* buffer for received data */ bzero (buf, 32768); /*clear buf*/
struct servent *sp; struct hostent *hp; char *endptr; short port; /* port number */
int op = 1; /* needed for sockopt */
/* parse command line */ if(argc != 2) printf("usage: %s \n", argv[0]), exit(0); else host = 0, sport = argv[1];
/* clear fd lists */ FD_ZERO(&master); FD_ZERO(&read_fds);
/* fill server address */ bzero ((void*)&srv_addr, sizeof(srv_addr)); /* fill zeroes */
srv_addr.sin_family = PF_INET; srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
/* fill port */ port = strtol( sport, &endptr, 0); if( *endptr == '\0' ) srv_addr.sin_port = htons(port); else { error(1,0,"unknown service: %s\n",sport); }
/* Create TCP based socket */ srv_st = socket(PF_INET, SOCK_STREAM, 0); if( srv_st < 0 ) error(1, errno, "error socket");
/* set SO_REUSEADDR option */ res = setsockopt(srv_st, SOL_SOCKET, SO_REUSEADDR, (const char*)&op,sizeof(op)); if(res) error(1, errno, "error setsockopt");
/* bind server socket to srv_addr */ res = bind(srv_st, (struct sockaddr*)&srv_addr, sockaddrsize); int pt = 50000; while (res) { if ( res < 0 ) { error(0, errno, "error bind, try again with port %d",pt); srv_addr.sin_port = htons(pt++); if ( pt >= 55000 ) error(1,0,"error bind, no enough ports in range"); res = bind(srv_st, (struct sockaddr*)&srv_addr, sockaddrsize); } else error(1, errno, "error bind"); }
/* create queue for clients requests */ res = listen(srv_st, NLISTEN); if(res == -1) error(1, errno, "listen");
/* add srv_st to master fd list */ FD_SET(srv_st, &master);
/* keep track of the biggest file descriptor */ fdmax = srv_st;
/* main loop */ for(;;) { read_fds = master; /* copy master list */
/* waiting new connection or data */ if (select( fdmax+1, &read_fds, NULL, NULL, NULL) == -1) { error(1, errno, "select"); }
/* run through the existing connections looking for data to read */ for( i=0; i<=fdmax; i++) { if(FD_ISSET(i, &read_fds)) /* we have got new data */ { if( i == srv_st ) { /* wait new connection */ clt_st = accept(srv_st, (struct sockaddr*)&clt_addr, &sockaddrsize); if( clt_st < 0) error(0, errno,"error accept"); else { FD_SET(clt_st, &master); /* add new socket to master */ if( clt_st > fdmax ) fdmax = clt_st; /* keep max descriptor */ } } else { /* got new data */ res = read(i, buf, sizeof(buf));
if( res <= 0) { /* client closed connection */ if( res == 0 ) { /* close socket and del i from master */ close(i); FD_CLR(i, &master); } } else { /* we have got a msg in buf from i client */ /* send message back */ printf ("recieved %d bytes\n",res); for(j = 0; j <=fdmax; j++) { if(FD_ISSET(j, &master)) { if((j != srv_st) && (j != i)) { res = write(j, buf, res); if( res == -1 ) error(0,errno,"send"); printf ("sent %d bytes to fd=%d\n",res,j); } } } } } } } } /* close srv_st socket */ close (srv_st); return 0; } и никаких дополнительных массивов и списков не нужно, в master хранятся все открытые дескрипторы... а так тут много чего нету, обработки всяких ошибок и тп (в частности если клиент отвалится по таймауту)... и вообще я бы смотрел в сторону libevent/libev и тп если нужен такой функционал...
благодарствую
|
03 фев 2012, 16:03 |
|