Ограничить и идентифицировать клиентов TCP

У меня есть эта программа, которая является прототипом для игры connectfour, как домашнее задание. Пока все хорошо, но у меня есть главный вопрос: как мне ограничить клиентов только двумя из них, а также, как я могу легко идентифицировать их, когда я собираюсь проверить, какой выбор столбца происходит из какого?

    #include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <pthread.h>

//used port
#define PORT 6660
//array limits
#define WIDTH 7
#define HEIGTH 6

//error code for some applications
extern int errno;

//static column variables

static int gameVariables [WIDTH] = {6, 6, 6, 6, 6, 6, 6};
static char gameArray[HEIGTH][WIDTH];

static void *treat(void *);//function called by every thread
typedef struct thData
{
  pthread_t idThread; //id Thread
  int cl;//descriptor returned by accept
}thData;

//Thread *threadsPool; //Threads array

//int sd;//listenning socket descriptor
//int nthreads; //number of threadsPool

//pthread_mutex_t mlock = PTHREAD_MUTEX_INITIALIZER; //mutex variable
static void *treat(void *);
//void raspunde (void *);
void connectFour(void *);

void printArray( char array[HEIGTH][WIDTH])
{
  int k, j;
 for( k = 0; k < HEIGTH; k++ )
    {
      for( j=0; j < WIDTH; j++ )
        printf("%c ", array[k][j]);
      printf("\n");
    }
}

int main( )
{
  //game array inialization
  int k, j;
  for( k = 0; k < HEIGTH; k++ )
    for( j = 0; j < WIDTH; j++ )
      gameArray[k][j] = (char) 79;


   printArray(gameArray);

  struct sockaddr_in server; //structure used by server
  //void threadCreate(int);
  struct sockaddr_in from;
  int message;
  int sd;
  int pid;
  pthread_t th[100];
  int i = 0;
  /*if(argc < 2)
  {
    fprintf(stderr, "Error: first argument is the number of thread\n");
    exit(1);
  } 

  nthreads = atoi(argv[1]);
  if(nthreads <= 0)
  {
    fprintf(stderr,"Error: number of threads invalid\n");
    exit(1);
  }

  threadsPool = calloc(sizeof(Thread), nthreads);
*/
  //create socket
  if((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
  {
    perror("[SERVER] Error at socket\n");
    return errno;
  }

  //using SO_REUSEADDR
  int on = 1;
  setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

  //preparing data structures
  bzero(&server, sizeof(server));
  bzero(&from, sizeof(from));

  server.sin_family = AF_INET;
  server.sin_addr.s_addr = htonl(INADDR_ANY);
  server.sin_port = htons(PORT);

  //bind the socket
  if(bind(sd, (struct sockaddr *) &server, sizeof(struct sockaddr) )== -1)
  {
    perror("[SERVER] Error at bind\n");
    return errno;
  }

  //server listening
  if(listen(sd, 2) == -1)
  {
    perror("[SERVER] Error at listen\n");
    return errno;
  }

 /* printf("Number of threads %d\n", nthreads);
  fflush(stdout);

  int i;
  for(i = 0; i < nthreads; i++)
    threadCreate(i);

  //serving concurrent clients using threads
  for( ; ; )
  {
    printf("[SERVER] Listening at port : %d", PORT);
    pause();
  }//for
*/
  //serving clients
  for( ; ; )
  {
    int client;
    thData *td; //parameter executed by thread
    int length = sizeof(from);

    printf("[SERVER] Waiting at port : %d\n", PORT);
    fflush(stdout);
    //accept client
    if((client = accept (sd, (struct sockaddr *) &from, &length)) < 0)
    {
      perror ("[SERVER]Error at accept\n");
      continue;
    }
    //connection established
    int idThread; //thread id
    int cl;

    td = (struct thData*)malloc(sizeof(struct thData));
    td -> idThread = i++;
    td -> cl = client;

    pthread_create (&th[i], NULL, &treat, td);
  } //for
};//main

static void *treat(void * arg)
{   
  struct thData tdL; 
  tdL= *((struct thData*)arg);  
  printf ("[thread]- %d - Waiting message\n", tdL.idThread);
  fflush (stdout);     
  pthread_detach(pthread_self());   
  connectFour((struct thData*)arg);
  /* am terminat cu acest client, inchidem conexiunea */
  close ((int)arg);
  return(NULL); 

};

/*
void raspunde (void *arg)
{
  int i = 0;
  char message[50], message2[100];
  struct thData tdL;
  tdL = *((struct thData*) arg);
  bzero(message, 50);
  if(read(tdL.cl, message, 50) <= 0)
  {
    printf("[thread %d]\n", tdL.idThread);
    perror("Error at read from client\n");
  }

  printf("[thread %d] Message was received %s\n", tdL.idThread, message);
  //preparing answer
  /*bzero(message2, 100);
  strcat(message2, "Hello, ");
  strcat(message2, message);
  printf("[thread %d] Sending back message %s\n", tdL.idThread, message2);

  //returning message
  if(write(tdL.cl, message2, 100) <= 0)
  {
    printf("[thread %d]\n", tdL.idThread);
    perror("[thread] Error at write\n");
  }
  else 
    printf("[thread %d] Message was sent with success\n", tdL.idThread);
};
*/

void connectFour( void *arg)
{

  int playerPick;
  char message[50];

  struct thData tdL;
  tdL = *((struct thData*) arg);
  bzero(message, 2);

  if(read (tdL.cl, message, 50) <= 0)
  {
    printf("[thread %d]\n", tdL.idThread );
    perror("Error at read from client\n");
  }

  printf ("[thread %d]Column pick received is : %s\n", tdL.idThread, message);
  playerPick = atoi(message);

  printf("playerPick is : %d\n", playerPick);
  fflush(stdout);
  switch(playerPick)
  {
    case 1:
     if(gameVariables[0] >0 && gameVariables[0] < 7)
      {
        --gameVariables[0];
        gameArray[gameVariables[0]][0] = (char) 82;
      }
      printArray(gameArray);
      break;
    case 2:

      if(gameVariables[1] >0 && gameVariables[1] < 7)
      {
        --gameVariables[1];
        gameArray[gameVariables[1]][1] = (char) 82;
      }
      printArray(gameArray);
      break;
    case 3:
      if(gameVariables[2] >0 && gameVariables[2] < 7)
        {
          --gameVariables[2];
          gameArray[gameVariables[2]][2] = (char) 82;
        }
      printArray(gameArray);
      break;
    case 4:
      if(gameVariables[3] >0 && gameVariables[3] < 7)
        {
          --gameVariables[3];
          gameArray[gameVariables[3]][3] = (char) 82;
        }
      printArray(gameArray);
      break;
    case 5:
      if(gameVariables[4] >0 && gameVariables[4] < 7)
      {
        --gameVariables[4];
        gameArray[gameVariables[4]][4] = (char) 82;
      }
      printArray(gameArray);
      break;
    case 6:
      if(gameVariables[5] >0 && gameVariables[5] < 7)
      {
        --gameVariables[5];
        gameArray[gameVariables[5]][5] = (char) 82;
      }
      printArray(gameArray);
      break;
    case 7:
      if(gameVariables[6] >0 && gameVariables[6] < 7)
      {
        --gameVariables[6];
        gameArray[gameVariables[6]][6] = (char) 82;
      }
      printArray(gameArray);
      break;

  }
  printf("%d %d %d %d %d %d %d\n", gameVariables[0], gameVariables[1], gameVariables[2], gameVariables[3], gameVariables[4], gameVariables[5], gameVariables[6]);


}

;

1 ответ

Решение

Вы просто сохраняете счетчик, который вы проверяете, принимая соединения. Когда клиент подключается, вы проверяете счетчик и, если он превышает лимит, затем закрываете соединение, иначе вы сохраняете соединение и увеличиваете счетчик. Когда клиент отключается (по какой-либо причине), вы уменьшаете счетчик.


Важно, чтобы вы фактически приняли все соединения, даже если вы сразу же закроете их снова. Это потому, что очереди сокетов ждут accept не безграничен После того, как вы заполните его, клиенты больше не смогут подключиться.

Другие вопросы по тегам