限制和识别客户端TCP

时间:2015-12-24 17:27:13

标签: c tcp clients

我有这个程序是connectfour游戏的原型,作为家庭作业项目。 到目前为止一直很好,但我有一个重要的问题,我如何将客户限制在其中只有2个,而且,当我要验证哪个列选择来自哪一个时,如何轻松识别它们?

    #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 个答案:

答案 0 :(得分:1)

您只需保留一个在接受连接时检查的计数器。当客户端连接时,检查计数器,如果超出限制,则关闭连接,否则保持连接并增加计数器。当客户端断开连接(无论出于何种原因)时,您会减少计数器。

您实际接受所有连接非常重要,即使您只是立即再次关闭它们。这是因为等待class LocaleMiddleware { public function handle($request, Closure $next) { $default = config('app.locale'); // 2. retrieve selected locale if exist (otherwise return the default) $locale = Session::get('my_project.locale', $default); // 3. set the locale App::setLocale($locale); return $next($request); } } 的套接字队列不是无限的。一旦填满,就没有更多的客户能够连接。