Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Kursovaya_otchyot_OS.doc
Скачиваний:
7
Добавлен:
13.09.2019
Размер:
243.71 Кб
Скачать

Исходный код server.C

#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <getopt.h>

#include <sys/time.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <arpa/inet.h>

#include <errno.h>

#include <string.h>

#include <unistd.h>

#include <fcntl.h>

#include <pthread.h>

#include <time.h>

#include "board.h"

#include "error.h"

struct games_info{

char ch_ip1[MAX_CH_IP],ch_ip2[MAX_CH_IP],bufer[MAXLINE];

int connfd1,connfd2,id,mtx1,mtx2,oc,x,y,b;

pthread_mutex_t mutex1,mutex2;

board cletka;

} *games;

struct client_info

{

char ch_ip[MAX_CH_IP];

int connfd;

};

int listenfd,connfd,max_count_game=1,n_port=7777,ID=1;

static pthread_mutex_t mutex_list_games;

int com_str(int argc, char **argv,int *cg,int *pr)

{

const char* short_options = "g:p:";

const struct option long_options[] =

{

{"count-games",required_argument,NULL,200},

{"game-server-port",required_argument,NULL,201},

{NULL,0,NULL,0}

};

int rez;

int option_index;

while ((rez=getopt_long(argc,argv,short_options,long_options,&option_index))!=-1)

{

switch(rez)

{

case 200:

case 'g':

{

if (optarg!=NULL)

{

*cg=atoi(optarg);

if (*cg<=0)

{

printf("chisl\n");

return -1;

}

}

break;

}

case 201:

case 'p':

{

if (optarg!=NULL)

{

*pr=atoi(optarg);

if (*pr<=0)

{

printf("chisl\n");

return -1;

}

}

break;

}

}

}

return 0;

}

void creat_list(struct menu_type mas[],int *kol)

{

int i=1,k=0;

char pnkt1[]="Создать игру\0",pnkt2[]="Обновление списка\0";

pthread_mutex_lock(&mutex_list_games);

mas[k].id=-1;

strncpy(mas[k].ip,pnkt1,MAX_CH_IP);

k=1;

for (i=0;i<max_count_game;i++)

if (games[i].connfd1!=-1&&games[i].connfd2==-1)

{

strcpy(mas[k].ip,games[i].ch_ip1);

mas[k].id=games[i].id;

k++;

}

mas[k].id=-2;

strncpy(mas[k].ip,pnkt2,MAX_CH_IP);

*kol=k;

pthread_mutex_unlock(&mutex_list_games);

}

void *work_with_client(void *arg)

{

struct client_info *inf=(struct client_info *) arg;

int g,k,n,ot,b=1,t,oc,i,j,hod=0;

struct menu_type *mas;

fd_set readset;

struct timeval timeout;

mas=calloc(max_count_game+2,sizeof(struct menu_type));

creat_list(mas,&k);

k++;

error_pol_return(write(inf->connfd,&k,sizeof(int)),"Error",0);

error_pol_return(write(inf->connfd,mas,sizeof(struct menu_type)*k),"Error",0);

while (b)

{

error_pol_return(read(inf->connfd,&ot,sizeof(ot)),"Error",0);

switch (ot)

{

case 1://zapros

creat_list(mas,&k);

k++;

error_pol_return(write(inf->connfd,&k,sizeof(k)),"Error",0);

error_pol_return(write(inf->connfd,mas,sizeof(struct menu_type)*k),"Error",0);

break;

case 2://creat game

pthread_mutex_lock(&mutex_list_games);

for (i=0;i<max_count_game;i++)

if (games[i].connfd1==-1&&games[i].connfd2==-1)

{

g=i;

pthread_mutex_unlock(&games[g].mutex1);

pthread_mutex_unlock(&games[g].mutex2);

t=2;

error_pol_return(write(inf->connfd,&t,sizeof(int)),"Error",0);

t=g+1;

error_pol_return(write(inf->connfd,&t,sizeof(int)),"Error",0);

b=0;

games[i].id=ID++;

oc=1;

games[i].connfd1=inf->connfd;

games[g].mtx1=games[g].mtx2=0;

strcpy(games[i].ch_ip1,inf->ch_ip);

printf("Клиент %s создал игру\n",inf->ch_ip);

break;

}

pthread_mutex_unlock(&mutex_list_games);

if (i==max_count_game)

{

t=-2;

error_pol_return(write(inf->connfd,&t,sizeof(int)),"Error",0);

}

break;

case 3://connect game

error_pol_return(read(inf->connfd,&ot,sizeof(ot)),"Error",0);

pthread_mutex_lock(&mutex_list_games);

for (i=0;i<max_count_game;i++)

if (games[i].id==ot)

{

if (games[i].connfd2==-1)

{

games[i].connfd2=inf->connfd;

strcpy(games[i].ch_ip2,inf->ch_ip);

b=0;

oc=2;

games[i].oc=2;

g=i;

t=3;

error_pol_return(write(inf->connfd,&t,sizeof(int)),"Error",0);

pthread_mutex_lock(&games[g].mutex1);

games[g].mtx1=1;

pthread_mutex_unlock(&games[g].mutex1);

printf("Клиент %s подключился к игре %s\n",inf->ch_ip,games[i].ch_ip1);

}

else

{

t=-3;

error_pol_return(write(inf->connfd,&t,sizeof(int)),"Error",0);

}

break;

}

pthread_mutex_unlock(&mutex_list_games);

break;

case 6://disconnect

printf("Клиент %s отключился\n",inf->ch_ip);

return 0;

}

}

if (oc==1)

{

while (1)

{

errno=0;

fcntl(inf->connfd, F_SETFL, FNDELAY|fcntl(inf->connfd, F_GETFL, 0));

n=read(inf->connfd,&ot,sizeof(ot));

fcntl(inf->connfd, F_SETFL, ~FNDELAY&fcntl(inf->connfd, F_GETFL, 0));

if (errno!=11) goto the_end;

if (n>0&&ot==6)

{

printf("Клиент %s отключился\n",inf->ch_ip);

pthread_mutex_lock(&mutex_list_games);

games[g].connfd1=-1;

pthread_mutex_unlock(&mutex_list_games);

goto the_end;

}

pthread_mutex_lock(&games[g].mutex1);

if (games[g].mtx1==1)

{

t=4;

error_pol_return(write(inf->connfd,&t,sizeof(int)),"Error",0);

games[g].mtx1=0;

games[g].oc=1;

pthread_mutex_unlock(&games[g].mutex1);

break;

}

pthread_mutex_unlock(&games[g].mutex1);

}

}

for (i=0;i<2;i++)

for (j=0;j<2;j++)

games[g].cletka[i][j]=EMPTY;

games[g].mtx2=0;

while (1)

{

FD_ZERO(&readset);

FD_SET(inf->connfd,&readset);

timeout.tv_sec=0;

timeout.tv_usec=500;

fcntl(inf->connfd, F_SETFL, FNDELAY|fcntl(inf->connfd, F_GETFL, 0));

n=select(inf->connfd+1, &readset, NULL, NULL, &timeout);

fcntl(inf->connfd, F_SETFL, ~FNDELAY&fcntl(inf->connfd, F_GETFL, 0));

if (n>0)

{

read(inf->connfd,&ot,sizeof(ot));

switch (ot)

{

case 4://text

error_1_goto(read(inf->connfd,&t,sizeof(int)),"Error",the_end);

error_1_goto(read(inf->connfd,&games[g].bufer,t),"Error",the_end);

games[g].bufer[t]='\0';

if (oc==1)

{

pthread_mutex_lock(&games[g].mutex2);

games[g].mtx2=2;

pthread_mutex_unlock(&games[g].mutex2);

}

else

{

pthread_mutex_lock(&games[g].mutex1);

games[g].mtx1=2;

pthread_mutex_unlock(&games[g].mutex1);

}

break;

case 5://hod

if (games[g].oc==oc)

{

error_1_goto(read(inf->connfd,&t,sizeof(int)),"Error",the_end);

games[g].x=t;

error_1_goto(read(inf->connfd,&t,sizeof(int)),"Error",the_end);

games[g].y=t;

if (games[g].cletka[games[g].y][games[g].x]==EMPTY)

{

if (games[g].oc==1)

games[g].cletka[games[g].y][games[g].x]=CROSS;

else

games[g].cletka[games[g].y][games[g].x]=ZERO;

t=6;

error_pol_goto(write(inf->connfd,&t,sizeof(int)),"Error",the_end);

if (oc==1)

{

hod++;

pthread_mutex_lock(&games[g].mutex2);

games[g].oc=2;

games[g].mtx2=3;

pthread_mutex_unlock(&games[g].mutex2);

}

else

{

pthread_mutex_lock(&games[g].mutex1);

games[g].oc=1;

games[g].mtx1=3;

pthread_mutex_unlock(&games[g].mutex1);

}

tPosSign sign;

if (victory(games[g].cletka,&sign,&t,&t))

{

if (games[g].oc==2)

printf("Клиент %s победил %s\n",games[g].ch_ip1,games[g].ch_ip2);

else

printf("Клиент %s победил %s\n",games[g].ch_ip2,games[g].ch_ip1);

if (sign==CROSS)

{

t=9;

error_pol_goto(write(inf->connfd,&t,sizeof(int)),"Error",the_end);

pthread_mutex_lock(&games[g].mutex2);

games[g].mtx2=4;

pthread_mutex_unlock(&games[g].mutex2);

goto the_end;

}

else

{

t=9;

error_pol_goto(write(inf->connfd,&t,sizeof(int)),"Error",the_end);

pthread_mutex_lock(&games[g].mutex1);

games[g].mtx1=4;

pthread_mutex_unlock(&games[g].mutex1);

goto the_end;

}

goto the_end;

}

else

if (hod==5)

{

printf("Клиенты %s,%s сыграли вничью\n",games[g].ch_ip1,games[g].ch_ip2);

t=11;

error_pol_goto(write(inf->connfd,&t,sizeof(int)),"Error",the_end);

pthread_mutex_lock(&games[g].mutex2);

games[g].mtx2=6;

pthread_mutex_unlock(&games[g].mutex2);

goto the_end;

}

}

else

{

t=-6;

error_pol_goto(write(inf->connfd,&t,sizeof(int)),"Error",the_end);

}

}

break;

case 6://disconnect

if (oc==1)

{

pthread_mutex_lock(&games[g].mutex2);

games[g].mtx2=5;

pthread_mutex_unlock(&games[g].mutex2);

}

else

{

pthread_mutex_lock(&games[g].mutex1);

games[g].mtx1=5;

pthread_mutex_unlock(&games[g].mutex1);

}

goto the_end;

break;

}

}

if (oc==1)

{

pthread_mutex_lock(&games[g].mutex1);

if (games[g].mtx1!=0)

{

switch (games[g].mtx1)

{

case 2://text

t=5;

error_pol_goto(write(inf->connfd,&t,sizeof(int)),"Error",the_end);

t=strlen(games[g].bufer);

error_pol_goto(write(inf->connfd,&t,sizeof(int)),"Error",the_end);

error_pol_goto(write(inf->connfd,&games[g].bufer,t),"Error",the_end);

break;

case 3://hod prot

t=7;

error_pol_goto(write(inf->connfd,&t,sizeof(int)),"Error",the_end);

error_pol_goto(write(inf->connfd,&games[g].x,sizeof(int)),"Error",the_end);

error_pol_goto(write(inf->connfd,&games[g].y,sizeof(int)),"Error",the_end);

break;

case 4://fail

t=10;

error_pol_goto(write(inf->connfd,&t,sizeof(int)),"Error",the_end);

goto the_end;

break;

case 5://disconnect

t=8;

error_pol_goto(write(inf->connfd,&t,sizeof(int)),"Error",the_end);

goto the_end;

break;

case 6://nichia

t=11;

error_pol_goto(write(inf->connfd,&t,sizeof(int)),"Error",the_end);

goto the_end;

break;

}

}

games[g].mtx1=0;

pthread_mutex_unlock(&games[g].mutex1);

}

else

{

pthread_mutex_lock(&games[g].mutex2);

if (games[g].mtx2!=0)

{

switch (games[g].mtx2)

{

case 2://text

t=5;

error_pol_goto(write(inf->connfd,&t,sizeof(int)),"Error1",the_end);

t=strlen(games[g].bufer);

games[g].bufer[t]='\0';

error_pol_goto(write(inf->connfd,&t,sizeof(int)),"Error2",the_end);

error_pol_goto(write(inf->connfd,&games[g].bufer,t),"Error3",the_end);

break;

case 3://hod prot

t=7;

error_pol_goto(write(inf->connfd,&t,sizeof(int)),"Error",the_end);

error_pol_goto(write(inf->connfd,&games[g].x,sizeof(int)),"Error",the_end);

error_pol_goto(write(inf->connfd,&games[g].y,sizeof(int)),"Error",the_end);

break;

case 4://fail

t=10;

error_pol_goto(write(inf->connfd,&t,sizeof(int)),"Error",the_end);

goto the_end;

break;

case 5://fail

t=8;

error_pol_goto(write(inf->connfd,&t,sizeof(int)),"Error",the_end);

goto the_end;

break;

case 6://nichia

t=11;

error_pol_goto(write(inf->connfd,&t,sizeof(int)),"Error",the_end);

goto the_end;

break;

}

}

games[g].mtx2=0;

pthread_mutex_unlock(&games[g].mutex2);

}

}

the_end:;

if (oc==1)

{

t=8;

printf("Клиент %s отключился\n",games[g].ch_ip1);

write(games[g].connfd1,&t,sizeof(int));

if (games[g].connfd1!=-1)

close(games[g].connfd1);

pthread_mutex_lock(&mutex_list_games);

games[g].connfd1=-1;

pthread_mutex_unlock(&mutex_list_games);

games[g].mtx1=0;

b=1;

while (b)

{

pthread_mutex_lock(&games[g].mutex2);

if (games[g].mtx2==0) b=0;

pthread_mutex_unlock(&games[g].mutex2);

}

pthread_mutex_lock(&games[g].mutex2);

games[g].mtx2=5;

pthread_mutex_unlock(&games[g].mutex2);

return 0;

}

else

{

t=8;

printf("Клиент %s отключился\n",games[g].ch_ip2);

write(games[g].connfd2,&t,sizeof(int));

if (games[g].connfd2!=-1)

close(games[g].connfd2);

pthread_mutex_lock(&mutex_list_games);

games[g].connfd2=-1;

pthread_mutex_unlock(&mutex_list_games);

games[g].mtx2=0;

b=1;

while (b)

{

pthread_mutex_lock(&games[g].mutex1);

if (games[g].mtx1==0) b=0;

pthread_mutex_unlock(&games[g].mutex1);

}

pthread_mutex_lock(&games[g].mutex1);

games[g].mtx1=5;

pthread_mutex_unlock(&games[g].mutex1);

return 0;

}

}

int main(int argc, char **argv)

{

unsigned int len;

struct client_info *temp;

struct sockaddr_in servaddr,clnaddr;

char adr[15]/*,port[5]*/;

pthread_t tid;

int i;

com_str(argc,argv,&max_count_game,&n_port);

if (max_count_game<1)

{

printf("Error count game\n");

return -1;

}

error_0_return(games=calloc(max_count_game,sizeof(struct games_info)),"Memory",-1);

for (i=0;i<max_count_game;i++)

{

pthread_mutex_init(&games[i].mutex1,NULL);

pthread_mutex_init(&games[i].mutex2,NULL);

games[i].connfd1=games[i].connfd2=-1;

games[i].mtx1=games[i].mtx2=0;

}

listenfd=socket(AF_INET,SOCK_STREAM,0);

bzero(&servaddr,sizeof(servaddr));

servaddr.sin_family=AF_INET;

servaddr.sin_addr.s_addr=htonl(INADDR_ANY);

servaddr.sin_port=htons(n_port);

error_1_return(bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr))," ",-1);

error_1_return(listen(listenfd, 1)," ",-1);

len=sizeof(clnaddr);

pthread_mutex_init(&mutex_list_games,NULL);

while (1)

{

error_1_continue(connfd=accept(listenfd,(struct sockaddr *) &clnaddr,&len)," ");

temp=malloc(sizeof(struct client_info));

inet_ntop(AF_INET,(struct sockaddr *) &clnaddr.sin_addr.s_addr, adr, 15);

snprintf(temp->ch_ip,MAX_CH_IP,"%s:%d",adr,ntohs(clnaddr.sin_port));

printf("Клиент %s присоединился\n",temp->ch_ip);

temp->connfd=connfd;

error_no0_continue(pthread_create(&tid,NULL,work_with_client,(void *)temp),"Error potok");

}

close(connfd);

return 0;

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]