Ciao a tutti, partendo dal sorgente di una chat multiutente basata su select() sto cercando di modificarla per implementare poi un gioco tipo battaglia navale con un server che controlla più partite tra più client.. quello che non riesco a fare ora è a chiedere al cliente, appena collegato, di scegliere un nickname e salvarlo nell'apposito campo user[x].nick dove x è il numero dell'utente. Qualcuno saprebbe dirmi come fare? Sto provando in più modi, ma ogni volta c'è qualcosa che non va.. o non me lo salva.. o lo salva però se poi provo a stamparlo solo sul client che lo ha inserito, lo stampa su tutti i client.. allego il sorgente dell'intero server..

Codice PHP:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>

#define SHOW 1      // command show
#define MESSAGE 2
#define HELP 3
#define NICK 4
#define NEWLINE 5



void write_to_socket(int target,char *buff_to_send,int len);
int check_for_command(char *buffer,int *p);
int is_fd_valid(int destination) ;
void type_writer(char *buf,int len,int fd);
typedef struct
{
  
int id;  /* socket descripter */
  
char nick[30]; /* store the nick here */
  
short flag_nick;
}
USER;


USER user[20];
int usercount=0;

int main(int argcchar *argv[])
{
  
fd_set master;   // master file descriptor list
  
fd_set read_fds// temp file descriptor list for select()
  
int PORT;                // porta sulla quale il server resta in ascolto
  
struct sockaddr_in myaddr;     // server address
  
struct sockaddr_in remoteaddr// client address
  
int fdmax;        // maximum file descriptor number
  
int listener;     // listening socket descriptor
  
int newfd;        // newly accept()ed socket descriptor
  
char buf[1024];    // buffer for client data
  
int nbytes;
  
int yes=1;        // for setsockopt() SO_REUSEADDR, below
  
int addrlen;
  
int ij,k,tmp,destination=0;
  
int str_len;
  
char c;
  
char *tmp_ptr;
  
//USER user[20];
  //int usercount=0;
  
bzero(user,sizeof(USER));

  
FD_ZERO(&master);    // clear the master and temp sets
  
FD_ZERO(&read_fds);
  
  
  if (
argc != 2) {
    
fprintf(stderr"Sintassi: %s <porta>\n"argv[0]);
    exit(
4);
  }

  
PORT=atoi(argv[1]);

  
// get the listener
  
if ((listener socket(AF_INETSOCK_STREAM0)) == -1) {
    
perror("socket error");
    exit(
1);
  }

  
// lose the pesky "address already in use" error message
  
if (setsockopt(listenerSOL_SOCKETSO_REUSEADDR, &yes,
    
sizeof(int)) == -1) {
    
perror("setsockopt error");
    exit(
1);
  }

  
// bind
  
myaddr.sin_family AF_INET;
  
myaddr.sin_addr.s_addr INADDR_ANY;
  
myaddr.sin_port htons(PORT);
  
memset(&(myaddr.sin_zero), '\0'8);
  if (
bind(listener, (struct sockaddr *)&myaddrsizeof(myaddr)) == -1) {
    
perror("bind error");
    exit(
1);
  }

  
// listen
  
if (listen(listener10) == -1) {
    
perror("listen error");
    exit(
1);
  }

  
// add the listener to the master set
  
FD_SET(listener, &master);

  
// keep track of the biggest file descriptor
  
fdmax listener// so far, it's this one

  // main loop
  
for(;;) {
    
read_fds master// copy it
    
if (select(fdmax+1, &read_fdsNULLNULLNULL) == -1) {
      
perror("select");
      exit(
1);
    }

    
// run through the existing connections looking for data to read
    
for(0<= fdmaxi++) {
      if (
FD_ISSET(i, &read_fds)) { // we got one!!
    
if (== listener) {
      
// handle new connections
      
addrlen sizeof(remoteaddr);
      if ((
newfd accept(listener, (struct sockaddr *)&remoteaddr,
          &
addrlen)) == -1) { 
        
perror("accept error");
      } else {
        
FD_SET(newfd, &master); // add to master set
        
if (newfd fdmax) {    // keep track of the maximum
          
fdmax newfd;
        }
        
user[usercount].id=newfd;
        ++
usercount;
        
printf(">> Accettata nuova connessione dal client %s sul socket %d\n"inet_ntoa(remoteaddr.sin_addr), newfd);
        
bzero(buf,sizeof(buf));
        
strcpy(buf,"\n\n\n\n\n\n\n\n\n\n\n********************************************************************************\n");
        
str_len=strlen(buf);
        
write_to_socket(newfd,buf,str_len);

        
        
bzero(buf,sizeof(buf));
        
strcpy(buf,"\n\t\t\t   ~~~~ BATTAGLIA NAVALE ~~~~\n\n");
        
str_len=strlen(buf);
        
type_writer(buf,str_len,newfd);
        
        
user[1].flag_nick=1;
        
strncpy(user[1].nick,"nick",30);

        
bzero(buf,sizeof(buf));
        
strcpy(buf,"********************************************************************************\n\n"
        "\t\t\t~Type /SHOW/ to list all online users\n\n"
        "\t~ To send a message to everyone in the room just type the message and press enter\n\n"
        "\t\t~ Type /numeric-user/ to send a message to particular user only\n\n"
        "\t\t ex: /6/ Hi number 6 how r u\n\n"
        "\t\t\t~ Type /HELP/ to see server commands\n\n"
        "********************************************************************************\n\n\n>>"
);
            
/* sprintf(buf,"Il nickname scelto e': ",user[1].nick);
        str_len=strlen(buf);
        write_to_socket(i,buf,str_len); */
        
        
str_len=strlen(buf);
        
write_to_socket(newfd,buf,str_len);
        
        
      }
    } else {
      
// handle data from a client
      
if ((nbytes recv(ibufsizeof(buf), 0)) <= 0) {
        
// got error or connection closed by client
        
if (nbytes == 0) {
          
// connection closed
          
printf(">> Socket %d chiuso. Il client %s si e' disconnesso.\n"iinet_ntoa(remoteaddr.sin_addr));
        } else {
          
perror("recv");
        }
        
close(i); // bye!
        
FD_CLR(i, &master); // remove from master set
      
} else {

        
// we got some data from a client
        //printf("\n%s\n",buf);
        
for(0<= fdmaxj++) {
          
// send to everyone!
          
if (FD_ISSET(j, &master)) {
        
// except the listener and ourselves
        
if (!= listener && != i) {
          switch(
check_for_command(buf,&destination))
          {
            case 
SHOW
              
//strcpy(buf,"Got the command request :-)\n>>\r\n" );
              //str_len=strlen(buf);
              
kusercount-1;
              
bzero(buf,sizeof(buf));
              while(
k>=0)
              {

            
sprintf(buf,"<%d>\n>>",user[k].id);
            
str_len=strlen(buf);
            
write_to_socket(i,buf,str_len);
            --
k;
              }

              
j=1111// to end the loop
              
break;
            case 
MESSAGE:
              if( 
is_fd_valid(destination) )
              {
            
tmp_ptr=buf;
            while(*
tmp_ptr==' ')
              ++
tmp_ptr;
            
c=destination;
            *(
tmp_ptr+1)=i+'0';//(char)destination;
            
tmp_ptr=strchr(buf,'\n');
            
//str_len=strlen(buf);
            
write_to_socket(destination,buf,tmp_ptr-buf+1);

            
printf("\nGood show\n");
              }
              else
              {
            
bzero(buf,sizeof(buf));
            
strcpy(buf,"Invalid user\n>>\r\n");
            
str_len=strlen(buf);
            
write_to_socket(i,buf,str_len);
              }
              
j=1111// to end the loop
              
break;

            case 
HELP:
              
bzero(buf,sizeof(buf));
              
strcpy(buf,"\n\n\n********************************************************************************\n\n\n"
              "\t\t\t~Type /SHOW/ to list all online users\n\n"
              "\t~ To send a message to everyone in the room \n"
              "\t\t\tjust type the message and press enter\n\n"
              "\t\t~ Type /numeric-user/ to send a message to particular user only\n\n"
              "\t\t\t\t ex: /6/ Hi number 6 how r u\n\n"
              "\t\t\t~ Type /HELP/ to see server commands\n\n\n>>"
              "********************************************************************************\n\n\n\n>>" 
);
              
str_len=strlen(buf);
              
write_to_socket(newfd,buf,str_len);

                
j=1111;
            break;
            case 
NEWLINE:
            
bzero(buf,sizeof(buf));
            
sprintf(buf,">>");
            
//str_len=strlen(buf);
            
write_to_socket(i,buf,strlen(buf));
            
j=1111;
            break;
            case 
NICK:
            
//printf("Got the nick\n");
            //bzero(buf,sizeof(buf));
            
printf(buf);
            
tmp_ptr=buf;
            
tmp_ptr+=6;
            for(
tmp=0;tmp<fdmax;++tmp)
            {
              if(
user[tmp].id==i)
                break;
            }
            
user[tmp].flag_nick=1;
            
strncpy(user[tmp].nick,tmp_ptr,10);
            
bzero(buf,sizeof(buf));
            
sprintf(buf,"%s Joined the room\r\n",user[tmp].nick);
            
str_len=strlen(buf);
            
write_to_socket(j,buf,str_len);
            
j=1111// to end the loop
            
break;
            default:
              
write_to_socket(j,buf,nbytes);
              break;
          }
        }
          }
        }
      }
    } 
      }
    }
  }

  return 
0;
}


void write_to_socket(int target,char *buff_to_send,int len)
{
  if( !
write(target,buff_to_send,len) )
  {
    
perror("Write");
    exit(
0);
  }
}

int check_for_command(char *buffer,int *p)
{
  
char tmp[6];
  
strncpy(tmp,buffer,5);
  while(*
buffer==' ')
    ++
buffer;
  if(!
strncmp(buffer,"/SHOW/",6) || !strncmp(buffer,"/show/",6) )
    return 
SHOW;
  else if(!
strncmp(buffer,"/HELP/",6) || !strncmp(buffer,"/help/",6) )
    return 
HELP;
  else if(!
strncmp(buffer,"/NICK/",6) || !strncmp(buffer,"/NICK/",6) )
    return 
NICK;

  else if((*
buffer=='/') && (*(buffer+2)=='/'))
  {
    *
p= *(buffer+1)-'0';
    return 
MESSAGE;
  }
  else if( *
buffer=='\r')
    return 
NEWLINE;

  else
    return 
0;


}

int is_fd_valid(int destination)
{
  
int i;
  for(
i=0;i<usercount;++i)
    if( 
user[i].id==destination)
      return 
1;
  return 
0;
}

void type_writer(char *buf,int lenint fd)
{
  
int i=0;
  for(
i=0;i<len;++i)
  {
    
write_to_socket(fd,buf+i,sizeof(char));
    
usleep(50000);
  }