我有这个程序是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]);
}
答案 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);
}
}
的套接字队列不是无限的。一旦填满,就没有更多的客户能够连接。