#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
#include <sys/select.h>
#include <signal.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void client_print(int *clients, int n_clients, int maxclients){
int i;
printf("n_clients=%d,max_clients=%d\n",n_clients, maxclients);
for(i=0; i<n_clients; i++){
printf("%d:%d\n",i,clients[i]);
}
}
void usage(char *prog){
fprintf(stderr, "Usage: %s port max_clients\n", prog);
exit (-1);
}
void die (const char *message) {
fprintf(stderr, "%s\n", message);
exit(-1);
}
//kliens több 0-as eleme:
int create_server(int port){
struct sockaddr_in addr;
int s;
printf("create_server\n");
s=socket(AF_INET, SOCK_STREAM, 0);
if(s<0){
perror("socket");
exit(-1);
}
addr.sin_family=AF_INET;
addr.sin_port=htons(port);
addr.sin_addr.s_addr=htonl(INADDR_ANY);
if(bind(s,(struct sockaddr *) &addr, sizeof (addr))<0){
perror("bind");
exit(-1);
}
if(listen(s, 4)<0) {
perror("listen");
exit(-1);
}
return (s);
}
void set_init (fd_set *fs, int *clients, int n_clients){
int i;
printf("set_init\n");
client_print(clients, n_clients, 0);
FD_ZERO(fs);
for(i=0;i<n_clients;i++){
FD_SET(clients[i],fs);
}
}
int set_select(fd_set *fs, int *clients, int n_clients) {
int i;
int maxfd=0;
printf("set_select\n");
client_print(clients, n_clients, 0);
for(i=0;i<n_clients; i++){
if(maxfd<clients[i]){
maxfd=clients[i];
}
}
maxfd++;
do {
i=select (maxfd, fs, 0,0,0);
}
while ((i<0)&&(errno==EINTR));
if (i<0) {
perror("select");
exit(-1);
}
for(i=0;i<n_clients;i++){
if(FD_ISSET(clients[i],fs)){
return(i);
}
}
die("???");
return(-1);
}
int read_from_client(int s) {
int n;
char buf[1024];
n=read(s,(void*) buf, 1024);
printf("read_from_client%d\n", s);
if(n<1) {
if(n<0) {
perror("read");
}
return(-1);
}
printf("Client %d sent: %s\n", s, buf);
return(0);
}
void client_close(int *clients, int n, int maxclients) {
int i;
close(clients[n]);
for(i=n; i<maxclients-1; i++) {
clients [i]=clients[i+1];
}
}
int client_accept(int *clients, int n_clients, int maxclients){
struct sockaddr_in addr;
socklen_t addrlen;
int s;
printf("client_accept\n");
client_print(clients, n_clients, maxclients);
if((s=accept(clients[0], (struct sockaddr*)&addr, &addrlen))<0){
perror("accept");
return(-1);
}
printf("Conncet from %s: %d \n",inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
if(n_clients==maxclients){
printf("Dropping connection \n");
close(s);
return (-1);
}
clients[n_clients]=s;
return(s);
}
int main (int argc, char ** argv) {
int port;
int n;
int maxclients;
int *clients;
int n_clients; //kliensek száma
fd_set read_set;
if(argc!=3) {
usage(argv[0]);
}
port=atoi(argv[1]);
maxclients=atoi(argv[2])+1;
clients =(int*)malloc (maxclients * sizeof(int));
if(!clients) {
die("out of memory");
}
n_clients=1;
clients[0]=create_server(port);
while (1){
set_init(&read_set, clients, n_clients);
n=set_select(&read_set, clients,n_clients);
if(n){
if(read_from_client(clients[n])<0) {
client_close(clients,n, maxclients);
n_clients--;
}
}
else { //if(n) ága
if(client_accept(clients, n_clients,maxclients)>0){
n_clients++;
printf("n_clients:%d\n", n_clients);
}
}
}
return(0);
}