📄 fives.c
字号:
close(user_fd[user]); FD_CLR(user_fd[user], &set_all); user_fd[user]=-1; game_state=GAME_READY; if (user==USER1){ write(user_fd[USER2], send_buf, PROTOCOLLEN); fsync(user_fd[USER2]); }else{ write(user_fd[USER1], send_buf, PROTOCOLLEN); fsync(user_fd[USER1]); }}//通知两个用户本回合棋盘落子情况和游戏输赢结果u_2005(int user_set, int row, int col, int currentuser, int result){//本函数发送实际有用数据长度是:sizeof(int)*6=24 protocol_num=(int *)send_buf; *protocol_num=NOTE_USER_RESULT;//协议号码sizeof(int) protocol_num=protocol_num+1; *protocol_num=user_set;//本回合落子用户sizeof(int) protocol_num=protocol_num+1; *protocol_num=row;//本回合落子行号sizeof(int) protocol_num=protocol_num+1; *protocol_num=col;//本回合落子列号sizeof(int) protocol_num=protocol_num+1; *protocol_num=currentuser;//下回合落子用户sizeof(int) protocol_num=protocol_num+1; *protocol_num=result;//游戏输赢结果sizeof(int) write(user_fd[USER1], send_buf, PROTOCOLLEN); fsync(user_fd[USER1]); write(user_fd[USER2], send_buf, PROTOCOLLEN); fsync(user_fd[USER2]);}//通知用户游戏可以开始了u_2006(int user){//本函数发送实际有用数据长度是:sizeof(int)=4 protocol_num=(int *)send_buf; *protocol_num=NOTE_USER_START;//协议号码sizeof(int) write(user_fd[user], send_buf, PROTOCOLLEN); fsync(user_fd[user]);}///////////////////////////////////////////////////协议处理函数///////////////////////////////////////////////////注册用户姓名p_1001(int user, char *buf){ protocol_num=(int *)buf; protocol_num=protocol_num+1; protocol_context=(char *)protocol_num; bcopy(protocol_context, user_name[user], USER_NAME_LEN); printf("user %d: %s coming !\n", user, user_name[user]);}//设置棋子位置p_1002(int user, char *buf){ int row, col, result; protocol_num=(int *)buf; protocol_num=protocol_num+1; row=*protocol_num;//横坐标 protocol_num=protocol_num+1; col=*protocol_num;//纵坐标 if(game_state==GAME_RUN){//游戏正在进行中 if(user==currentuser){//是本回合落子的用户 if(row>=0 && row<=ROWCOL && col>=0 && col<=ROWCOL \ && !(qipan[row][col]==USER1) && !(qipan[row][col]==USER2)){//如果落子的位置合法 qipan[row][col]=user;//本回合用户在指定位置落子 if(currentuser==USER1) currentuser=USER2;//交换下一回合落子用户 else currentuser=USER1; result=g_result();//判断输赢 switch (result) { case USER1 : {//USER1获胜//通知两个用户谁获胜,游戏结束,等待用户确认重新开始 game_state=GAME_OVER; u_2005(user, row, col, currentuser, result); break; } case USER2 : {//USER2获胜//通知两个用户谁获胜,游戏结束,等待用户确认重新开始 game_state=GAME_OVER; u_2005(user, row, col, currentuser, result); break; } case 2 : {//平局//通知两个用户谁获胜,游戏结束,等待用户确认重新开始 game_state=GAME_OVER; u_2005(user, row, col, currentuser, result); break; } default : {//未决出输赢继续游戏 u_2005(user, row, col, currentuser, result); break; } }printf("user %d: %s played[%d][%d], result is: %d, nextuser: %d\n", user, user_name[user], row, col, result, currentuser); } } }}//继续新一轮游戏p_1003(int user, char *buf){//user_flag是标志两个用户游戏结束后的同步变量,当两个用户同时决定继续游戏的时候才能继续进行 if(game_state==GAME_OVER){//游戏已经结束 if (user_flag[user]<=0) user_flag[user]=1; printf("user %d: %s require game continue.\n", user, user_name[user]); if(user_flag[USER1]>0 && user_flag[USER2]>0){ s_init(); u_2002(USER1); u_2002(USER2); game_state=GAME_RUN; } }}//通知服务器游戏可以开始了p_1004(int user, char *buf){//挨个通知两个用户游戏开始 s_init(); u_2002(USER1); u_2002(USER2); game_state=GAME_RUN;}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////游戏主函数int main(){ //初始化游戏变量 s_init(); //创建服务器socket if ((fd_listen=socket(AF_INET, SOCK_STREAM, 0))<0) printf("error: create socket !\n"); bzero(&addr_s, sizeof(addr_s)); addr_s.sin_family=AF_INET; addr_s.sin_addr.s_addr=htonl(INADDR_ANY); addr_s.sin_port=htons(PORT); if (bind(fd_listen, (struct sockaddr *)&addr_s, sizeof(addr_s))==-1){ printf("error: bind !\n"); exit(1); } if (listen(fd_listen, BACKLOG)==-1){ printf("error: (listen !\n"); exit(1); } //循环获得客户端的命令请求并处理 fd_max=fd_listen; user_fd[USER1]=-1; user_fd[USER2]=-1; FD_ZERO(&set_all); FD_SET(fd_listen, &set_all); fcntl(fd_listen, F_SETFL, O_NONBLOCK);//非阻塞 while(1){ set_temp=set_all; timeout.tv_sec=0; timeout.tv_usec=100000;//select函数持续十分之一秒 selectn=select(fd_max+1, &set_temp, NULL, NULL, &timeout); //有新用户连接 if (FD_ISSET(fd_listen, &set_temp)){ len=sizeof(addr_c); if((fd_conn=accept(fd_listen, (struct sockaddr *)&addr_c, &len))<0) printf("error: accept !\n"); if (user_fd[USER1]>-1 && user_fd[USER2]>-1) { u_2001(fd_conn);//提示用户已满 if (--selectn<=0) continue; }else{//保存用户fd if (user_fd[USER1]==-1) { user_fd[USER1]=fd_conn; }else if (user_fd[USER2]==-1){ user_fd[USER2]=fd_conn; } fcntl(fd_conn, F_SETFL, O_NONBLOCK);//非阻塞 FD_SET(fd_conn, &set_all); if (fd_conn>fd_max) fd_max=fd_conn; if (user_fd[USER1]>-1 && (user_fd[USER2]>-1)){//两个用户连接到服务器了,通知用户游戏开始 if (user_fd[USER1]>-1) u_2006(USER1); else u_2006(USER2); }else{//通知用户等待另一个用户连接 if(user_fd[USER1]>-1) u_2003(USER1); else u_2003(USER2); } if (--selectn<=0) continue; } } //正在游戏的用户1发送的请求 if (user_fd[USER1]>0 && FD_ISSET(user_fd[USER1], &set_temp)){ if ((len=read(user_fd[USER1], receive_buf, MAXLEN))==0) { u_2004(USER1);//一个用户退出游戏,重新设置用户和游戏变量,通知另一个用户等待新的用户到来 }else{//处理游戏用户发送的命令请求 temp=receive_buf; while(len>0){//若同一个用户同时发来多个处理请求,需要循环处理每一个具体的协议请求 s_delegate(USER1, temp); len=len - PROTOCOLLEN; if(len>0) temp=temp + PROTOCOLLEN; } } } //正在游戏的用户2发送的请求 if (user_fd[USER2]>0 && FD_ISSET(user_fd[USER2], &set_temp)){ if ((len=read(user_fd[USER2], receive_buf, MAXLEN))==0) {//有游戏用户退出了游戏 u_2004(USER2);//一个用户退出游戏,重新设置用户和游戏变量,通知另一个用户等待新的用户到来 }else{//处理游戏用户发送的命令请求 temp=receive_buf; while(len>0){ s_delegate(USER2, temp); len=len - PROTOCOLLEN; if(len>0) temp=temp + PROTOCOLLEN; } } } }//end of while}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -