LINUX操作系统实验 两个进程相互通信

1、编写C程序,使用Linux中的IPC机制,完成 “石头、剪子、布”的游戏。

决定写这篇是因为在网上都搜不到第二部分的实验内容,自己学会了之后决定写了这个实验的流程


第一部分使用的msgp代码,放了些其他类型的代码可以参考

msgq代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct Game   //游戏信息
{
    long Type;
    int Round;

};
void result_send(int num)     //发送出拳信息
{
    struct Game game;
    game.Type = 1;
    game.Round = rand() % 3;
    msgsnd(num, &game, sizeof(int), 0);
}
int result_announce(int a, int b)    //出拳结果的判断
{
    if ((a + 1 == b) || (a - 3 == b))
        return -1;    //a胜b
    else if (a == b)
        return 0;    //ab平局
    else
        return 1;    //a负b
}
void writeFile(int *result_list, int len)   //将每盘的结果存入文件
{
    int count_A = 0; 
    int count_B = 0;
    int pingju=0;
    FILE *fin;
    if( (fin = fopen( "result.txt", "w" )) == NULL ) 
        printf( "This file wasn't opened" );

    int i;
    for (i = 0; i < len ; i++)
    {
        switch(result_list[i])
        {
            case -1 :{
                count_A++;
                fprintf(fin, "NO.%d:A win\n", i + 1);
                printf("NO.%d:A win\n", i + 1);
                break;
            }
            case 0 : {
                pingju++;
                fprintf(fin, "NO.%d:end in a draw\n", i + 1);
                printf("NO.%d:end in a draw\n", i + 1);
                break;
            }
            case 1 : {
                count_B++;
                fprintf(fin, "NO.%d:B win\n", i + 1);
                printf("NO.%d:B win\n", i + 1);
                break;
            }
        }
    }

    printf("\nThe final result is A win:%ds \nB win:%ds \nend in a draw %ds\n",count_A,count_B,pingju);
    fprintf(fin, "\nThe final result is A win:%ds \nB win:%ds \nend in a draw %ds\n",count_A,count_B,pingju);
    fclose(fin);
}
int main()
{
    int times; 
    int key1 = 1234;
    int key2 = 5678;
    int *result_list;
    pid_t  pid1, pid2;  
    int msgid1,msgid2;
    msgid1 = msgget(key1, IPC_CREAT | 0666); //创建消息队列
    if(msgid1 == -1)
    {
        fprintf(stderr, "failed with error");
        exit(EXIT_FAILURE);
    }
    msgid2 = msgget(key2, IPC_CREAT | 0666); //创建消息队列
    if(msgid2 == -1)
    {
        fprintf(stderr, "failed with error");
        exit(EXIT_FAILURE);
    }
    printf("Game start,please input rounds:");
    scanf("%d", &times);
    result_list=(int*)malloc(times*sizeof(int));
    int i;
    for (i = 0; i < times; i++)
    {
        pid1 = fork();   //创建选手1
        if (pid1 == 0) 
        {
            srand((unsigned)time(0) * 3000 ); //以时间为种子
            result_send(msgid1);  //生成选手1的出拳信息并发送到信息队列
            exit(-1);
        }
        pid2 = fork();   //创建选手2
        if (pid2 == 0) 
        {
            srand((unsigned)time(NULL)*i ); //以时间为种子
            result_send(msgid2);  //生成选手2的出拳信息并发送到信息队列
            exit(-1);
        }

        if (pid1 < 0 || pid2 < 0)
        {
            fprintf(stderr, "Fork Failed");
            exit(-1);
        }
        else
        {
            wait(NULL);
            wait(NULL);
            struct Game game1;
            struct Game game2;
//printf("wait ok.\n");
       //从消息队列中取得选手1的出拳信息
            msgrcv(msgid1, &game1, sizeof(game1) - sizeof(long), 0, 0);
//printf("rcv1 ok.\n");
        //从消息队列中取得选手2的出拳信息
            msgrcv(msgid2, &game2, sizeof(game2) - sizeof(long), 0, 0); 
        //评判出拳结果
//printf("rcv2 ok.\n");
            int j = result_announce(game1.Round, game2.Round);
            //result_list[i] = result_announce(game1.Round, game2.Round); 
            result_list[i] = j;
        }
    }
//printf("end ok.\n");
    //将比赛结果写入文件
    writeFile(result_list, times);
    //删除消息队列
/*    if (msgctl(msgid1, IPC_RMID, 0) == -1)
    {
        fprintf(stderr, "msgctl(IPC_RMID) failed\n");
    }
    if (msgctl(msgid2, IPC_RMID, 0) == -1)
    {
        fprintf(stderr, "msgctl(IPC_RMID) failed\n");
    }
 */   exit(EXIT_SUCCESS);
}

pipe代码:

#include <unistd.h>  
#include <sys/types.h>  
#include <errno.h>  
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h> 
#include<time.h>

#define MAX_DATA_LEN   256  
#define DELAY_TIME 1  

/*
数据结构
0:石头
1:剪刀
2:布*/

/*judge函数返回值含义
1:甲赢
0:平局
-1:乙赢*/

int judge(char a,char b)   //胜负判定函数
{
    if(a==b)
        return 0;
    else
    {
        if(a=='0'&&b =='1')
            return 1;
        if(a=='0'&&b =='2')
            return -1;
        if(a=='1'&&b =='2')
            return 1;
        if(a=='1'&&b =='0')
            return -1;
        if(a=='2'&&b =='0')
            return 1;
        if(a=='2'&&b =='1')
            return -1;
    }
}


int main()  
{     
    /*创建第一个管道和第一个子进程*/
     pid_t pid;     
      
     int pipe_fd[2];    
     char buf[MAX_DATA_LEN];    
     char data[20];   
     int real_read, real_write;   //管道的读写操作
     
     memset((void*)buf, 0, sizeof(buf));   //清空缓冲区  
   
     if (pipe(pipe_fd) < 0)   //判断管道是否创建成功 
     {         
         printf("pipe create error\n");       
         exit(1);    
     }  
         
    if ((pid = fork()) == 0)     //创建第一个子进程
     {
     
         close(pipe_fd[0]);      // 子进程关闭读描述符      
         sleep(3);               //通过使子进程暂停3s等待父进程已关闭相应的写描述符  
                    
          //子进程在管道中写内容      
         srand(time(NULL));
         int i;
         for(i = 0;i<120;i++)
         {
             sprintf(data,"%d",rand()%3);//随机产生0-2的数字写入管道
             while(write(pipe_fd[1],data,strlen(data))==-1);//不断尝试写直到成功
         }   
  
         close(pipe_fd[1]);          
         exit(0);      
 }
 
   /*创建第二个管道和第二个子进程*/
     pid_t pid_1;    
       
     int pipe_fd_1[2];    
     char buf_1[MAX_DATA_LEN];    
     char data_1[20];   
     int real_read_1, real_write_1;
     
     memset((void*)buf, 0, sizeof(buf));   //清空缓冲区  
   
     if (pipe(pipe_fd_1) < 0)   //判断管道是否创建成功 
     {         
         printf("pipe create error\n");       
         exit(1);    
     }  
         
    if ((pid_1 = fork()) == 0)     //创建第一个子进程
     {
     
         close(pipe_fd_1[0]);      // 子进程关闭读描述符      
         sleep(3);               //通过使子进程暂停3s等待父进程已关闭相应的写描述符  
                    
          //子进程在管道中写内容      
         srand(time(NULL)+120);
         int i;
         for(i = 0;i<120;i++)
         {
             sprintf(data_1,"%d",rand()%3);//随机产生0-2的数字写入管道
             while(write(pipe_fd_1[1],data_1,strlen(data_1))==-1);//不断尝试写直到成功
         }   
  
         close(pipe_fd_1[1]);    //关闭子进程写描述符      
         exit(0);      
 }
 
   
         /*父进程*/
     else if (pid > 0)     
      {         
           /* 读取第一个管道的数据 */             
         close(pipe_fd[1]);      //父进程关闭写描述符      
         sleep(1);      //通过使父进程暂停1s等待子进程关闭相应的读描述符
               
         if((real_read = read(pipe_fd[0], buf, MAX_DATA_LEN)) > 0)     
           {          
             printf("读取选手甲数据成功!\n");  
           }     
                  
         close(pipe_fd[0]);     //关闭父进程读描述符   
         waitpid(pid, NULL, 0);  //收集子进程1退出信息
         
          /* 读取第二个管道的数据 */             
         close(pipe_fd_1[1]);      //父进程关闭写描述符      
         sleep(1);      //通过使父进程暂停1s等待子进程关闭相应的读描述符
               
         if((real_read_1 = read(pipe_fd_1[0], buf_1, MAX_DATA_LEN)) > 0)     
           {          
             printf("读取选手乙数据成功!\n\n");  
           }     
                  
         close(pipe_fd_1[0]);     //关闭父进程读描述符   
         waitpid(pid_1, NULL, 0);  //收集子进程2退出信息
           /*结束*/
         
           //判定比赛并公示结果
          int aw = 0,bw = 0,n_w = 0;
          int res = 0;
          int i;
          for(i = 0;i<120;i++){
              printf("第%d回合:",i+1);
              res = judge(buf[i],buf_1[i]);

              if(res == 1){
                  printf("甲赢!\n");
                  aw++;
                  }
              else if(res == -1){
                  printf("乙赢!\n");
                  bw++;
                  }
              else{
                  printf("平局!\n");
                  n_w++;
                  }
             }
             
          printf("\n比赛结果公示\n");
          printf("选手甲赢了:%d次\n",aw);
          printf("选手乙赢了:%d次\n",bw);
          printf("平局:%d次\n",n_w);
          exit(0);
       }   
          
             
     return 0;   
}
 

shm代码:

a:

#include<stdio.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<string.h>
#include<time.h>
#include<sys/sem.h>

typedef struct _test{
    int a_val;
    int b_val;
    int a_flag;
    int b_flag;
    int game_no;
    int stage;
}test;

void sem_p();
void sem_v();
void set_sem();
void del_sem();
int sem_id;

union semun{
    int val;
    struct semid_ds *buf;
    unsigned short *arry;
};

int pk[3][3] = {0,-1,1,1,0,-1,-1,1,0};
int other[3][3] = {0,2,1,1,0,2,2,1,0};
int you;
int arr[3];

int main(){
    srand((int)time(0));
    int shmid;
    test* shm;
    
    shmid = shmget((key_t)1236,sizeof(test),0666);    
    if(shmid == -1){
        printf("shmget failed\n");
        exit(EXIT_FAILURE);
    }
    printf("%d",shmid);

    shm = shmat(shmid,0,0);
    if (shm == (void*)-1){
        printf("shmat failed\n");
        exit(EXIT_FAILURE);
    }
    printf("\nMemory attached at %X\n",(int)shm);
    
    sem_id = semget((key_t)3000,1,0666|IPC_CREAT);

    int no=0;
    while(1){
        sem_p();
        if(shm->game_no==-1){
            sem_v();
            break;
        }
        if (shm->stage==0){
            if(no!=shm->game_no){
                no = shm->game_no;
                printf("-------------------\n");
                printf("game_no:%d\n",no);
            }
            if(shm->a_flag==0){
                shm->a_flag=1;
                shm->a_val = rand()%3;
                printf("you:%d\n",shm->a_val);
                you = shm->a_val;
            }
        }
        else if(shm->stage==1){
        
        }
        else if(shm->stage==2){
            if(shm->a_flag==0){
                shm->a_flag=1;
                int val=shm->a_val;
                printf("other:%d\n",other[you][(val==-1)?2:val]);
                if(val==0) {arr[0]++; printf("draw!\n");}
                if(val==1) {arr[1]++; printf("you win!\n");}
                if(val==-1){arr[2]++; printf("you lost!\n");}
                printf("-------------------\n");
            }
        }
        sem_v();
    }
    
    printf("draw:%d\nwin:%d\nlost:%d\n",arr[0],arr[1],arr[2]);    

    shmdt(shm);

}
void set_sem(){
    union semun sem_union;
    sem_union.val=1;
    semctl(sem_id,0,SETVAL,sem_union);
}

void del_sem(){
    union semun sem_union;
    semctl(sem_id,0,IPC_RMID,sem_union);
}

void sem_p(){
    struct sembuf sem_b;
    sem_b.sem_num = 0;
    sem_b.sem_op = -1;
    sem_b.sem_flg = SEM_UNDO;
    semop(sem_id,&sem_b,1);
}

void sem_v(){
    struct sembuf sem_b;
    sem_b.sem_num = 0;
    sem_b.sem_op = 1;
    sem_b.sem_flg = SEM_UNDO;
    semop(sem_id,&sem_b,1);
}
 

b:

#include<stdio.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<string.h>
#include<time.h>
#include<sys/sem.h>

typedef struct _test{
    int a_val;
    int b_val;
    int a_flag;
    int b_flag;
    int game_no;
    int stage;
}test;

void sem_p();
void sem_v();
void set_sem();
void del_sem();
int sem_id;

union semun{
    int val;
    struct semid_ds *buf;
    unsigned short *arry;
};

int pk[3][3] = {0,-1,1,1,0,-1,-1,1,0};
int other[3][3] = {0,2,1,1,0,2,2,1,0};
int you;
int arr[3];

int main(){
    srand((int)time(0));
    int shmid;
    test* shm;
    
    shmid = shmget((key_t)1236,sizeof(test),0666);    
    if(shmid == -1){
        printf("shmget failed\n");
        exit(EXIT_FAILURE);
    }
    printf("%d",shmid);

    shm = shmat(shmid,0,0);
    if (shm == (void*)-1){
        printf("shmat failed\n");
        exit(EXIT_FAILURE);
    }
    printf("\nMemory attached at %X\n",(int)shm);
    
    sem_id = semget((key_t)3000,1,0666|IPC_CREAT);

    int no=0;
    while(1){
        sem_p();
        if(shm->game_no==-1){
            sem_v();
            break;
        }
        if (shm->stage==0){
            if(no!=shm->game_no){
                no = shm->game_no;
                printf("-------------------\n");
                printf("game_no:%d\n",no);
            }
            if(shm->b_flag==0){
                shm->b_flag=1;
                shm->b_val = rand()%3;
                printf("you:%d\n",shm->b_val);
                you = shm->b_val;
            }
        }
        else if(shm->stage==1){
        
        }
        else if(shm->stage==2){
            if(shm->b_flag==0){
                shm->b_flag=1;
                int val=shm->b_val;
                printf("other:%d\n",other[you][(val==-1)?2:val]);
                if(val==0) {arr[0]++; printf("draw!\n");}
                if(val==1) {arr[1]++; printf("you win!\n");}
                if(val==-1){arr[2]++; printf("you lost!\n");}
                printf("-------------------\n");
            }
        }
        sem_v();
    }
    
    printf("draw:%d\nwin:%d\nlost:%d\n",arr[0],arr[1],arr[2]);    

    shmdt(shm);

}
void set_sem(){
    union semun sem_union;
    sem_union.val=1;
    semctl(sem_id,0,SETVAL,sem_union);
}

void del_sem(){
    union semun sem_union;
    semctl(sem_id,0,IPC_RMID,sem_union);
}

void sem_p(){
    struct sembuf sem_b;
    sem_b.sem_num = 0;
    sem_b.sem_op = -1;
    sem_b.sem_flg = SEM_UNDO;
    semop(sem_id,&sem_b,1);
}

void sem_v(){
    struct sembuf sem_b;
    sem_b.sem_num = 0;
    sem_b.sem_op = 1;
    sem_b.sem_flg = SEM_UNDO;
    semop(sem_id,&sem_b,1);
}
 

test:

#include<stdio.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/sem.h>
#include<string.h>

typedef struct _test{
    int a_val;
    int b_val;
    int a_flag;
    int b_flag;
    int game_no;
    int stage;
}test;

int pk[3][3] = {0,-1,1,1,0,-1,-1,1,0};

void sem_p();
void sem_v();
void set_sem();
void del_sem();
int sem_id;

union semun{
    int val;
    struct semid_ds *buf;
    unsigned short *arry;
};

int main(){
    int shmid;
    test* shm;
    
    shmid = shmget((key_t)1236,sizeof(test),0666|IPC_CREAT);    
    if(shmid == -1){
        printf("shmget failed\n");
        exit(EXIT_FAILURE);
    }
    printf("%d",shmid);

    shm = shmat(shmid,0,0);
    if (shm == (void*)-1){
        printf("shmat failed\n");
        exit(EXIT_FAILURE);
    }
    printf("\nMemory attached at %X\n",(int)shm);

    sem_id = semget((key_t)3000,1,0666|IPC_CREAT);
    set_sem();

    int no=0,debug=0,a,b;
    shm->a_flag=0;    shm->a_val = -2;
    shm->b_flag=0;    shm->b_val = -2;
    shm->game_no=1;
    shm->stage=0;
    while(1){
        sem_p();
        //printf("a:%d b:%d\n",shm->a_val,shm->b_val); sleep(1);
        if(shm->game_no==-1){
            sem_v();
            break;
        }
        if (shm->stage==0){
            if(no!=shm->game_no){
                no = shm->game_no;
                printf("-------------------\n");
                printf("game_no:%d\n",no);
            }
            if(shm->a_flag==1 && shm->b_flag==1) shm->stage=1;
        }
        else if(shm->stage==1){
            printf("a:%d\n",shm->a_val);
            printf("b:%d\n",shm->b_val);
            a = pk[shm->a_val][shm->b_val];
            b = pk[shm->b_val][shm->a_val];
            shm->a_val=a;
            shm->b_val=b;
            shm->a_flag=0;
            shm->b_flag=0;
            shm->stage=2;
        }
        else if(shm->stage==2){
            if(shm->a_flag==1 && shm->b_flag==1){
                shm->stage=0;
                shm->game_no++;
                shm->a_flag=0;
                shm->b_flag=0;
                printf("-------------------\n");
                if(shm->game_no > 100) shm->game_no=-1;
            }
        }
        sem_v();
    }

    shmdt(shm);

    int ret=0;
    ret = shmctl(shmid,IPC_RMID,NULL);
    if(ret<0){
        printf("shmctl error!\n");
    }

    del_sem();

    printf("finish");
}

void set_sem(){
    union semun sem_union;
    sem_union.val=1;
    semctl(sem_id,0,SETVAL,sem_union);
}

void del_sem(){
    union semun sem_union;
    semctl(sem_id,0,IPC_RMID,sem_union);
}

void sem_p(){
    struct sembuf sem_b;
    sem_b.sem_num = 0;
    sem_b.sem_op = -1;
    sem_b.sem_flg = SEM_UNDO;
    semop(sem_id,&sem_b,1);
}

void sem_v(){
    struct sembuf sem_b;
    sem_b.sem_num = 0;
    sem_b.sem_op = 1;
    sem_b.sem_flg = SEM_UNDO;
    semop(sem_id,&sem_b,1);
}
 

socket代码:

选手1:

#include<stdlib.h>
#include<time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
 
int main()
{
  int sockfd1 =-1;
  char game1;
  int len = 0;
   struct sockaddr_in address;
  int result;
  char ch='A';
  srand((unsigned)time(NULL));
 

  sockfd1 = socket(AF_INET, SOCK_STREAM, 0);
  address.sin_family = AF_INET;
    address.sin_addr.s_addr = inet_addr("127.0.0.1");
    address.sin_port = htons(9736);
    len = sizeof(address);

  result = connect(sockfd1, (struct sockaddr*)&address, len);

  if(result == -1)
    {
        perror("ops:client\n");
        exit(1);
    }
  for (int i=0;i<=100;i++){
     game1=rand()%3+'0';
    write(sockfd1, &game1, 1);

    read(sockfd1, &ch, 1);
    printf("result form server = %c\n",ch);
    printf("game1 form server = %c\n",game1);}
    close(sockfd1);
    exit(0);
}
 

选手2:

#include<stdlib.h>
#include<time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
 
int main()
{
  int sockfd2 =-1;
  char game2;
  int len = 0;
  char ch='A';
   struct sockaddr_in address;
  int result;
  srand((unsigned)time(NULL));


  sockfd2 = socket(AF_INET, SOCK_STREAM, 0);
  address.sin_family = AF_INET;//使用网络套接字
    address.sin_addr.s_addr = inet_addr("127.0.0.1");//服务器地址
    address.sin_port = htons(9736);//服务器所监听的端口
    len = sizeof(address);

  result = connect(sockfd2, (struct sockaddr*)&address, len);

  if(result == -1)
    {
        perror("ops:client\n");
        exit(1);
    }
    for (int i=0;i<=100;i++){
  game2=rand()%3+'0';
  write(sockfd2, &game2, 1);
    //从服务器获取数据
    read(sockfd2, &ch, 1);
    printf("result form server = %c\n", ch);
  printf("game2 form server = %c\n", game2);}
    close(sockfd2);
    exit(0);
}
 

裁判:

#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<signal.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
 {
     int server_sockfd = -1;
     int client_sockfd1 = -1;
    int client_sockfd2= -1;
     int client_len1 = 0;
     int client_len2 = 0;
     struct sockaddr_in server_addr;
     struct sockaddr_in client_addr1;
     struct sockaddr_in client_addr2;
     char game1;
     char game2;
     int count=0;
     int result;
     char ch='H';
     

     server_sockfd = socket(AF_INET,SOCK_STREAM,0);

     server_addr.sin_family = AF_INET;
     server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
     server_addr.sin_port = htons(9736);

     bind(server_sockfd,(struct sockaddr*)&server_addr,sizeof(server_addr));

     listen(server_sockfd, 100);

     signal(SIGCHLD, SIG_IGN);

   
         client_len1= sizeof(client_addr1);
         client_len2= sizeof(client_addr2);
         printf("Server waiting\n");

         client_sockfd1 =accept(server_sockfd,(struct sockaddr*)&client_addr1,&client_len1);
         client_sockfd2 =accept(server_sockfd,(struct sockaddr*)&client_addr2,&client_len2);
            for(int i=0;i<=100;i++)
            {
          
                read(client_sockfd2,&game2,1);
                read(client_sockfd1,&game1,1);
                
                sleep(3);
                if(game1==game2)
                {
                    ch='D';
                }
                if( (game1=='2'&&game2=='1')||(game1=='1'&&game2=='0')||(game1=='0'&&game2=='2'))
                {
                    ch='W';
                }
                if((game2=='2'&&game1=='1')||(game2=='1'&&game1=='0')||(game2=='0'&&game1=='2'))
                {
                    ch='L';
                }
                printf("game1:%c\n",game1);
                printf("game2:%c\n",game2);
                printf("%c\n",ch);
                write(client_sockfd1,&ch,1);
                write(client_sockfd2,&ch,1);
             } close(client_sockfd1);
                close(client_sockfd2);
                exit(0);
            
            /*else
            {
                /*close(client_sockfd1);
                close(client_sockfd2);
            }*/
            
 }

实验结果:

2、修改上述程序,使之能够在网络上运行该游戏。

这部分使用的代码是上面的socket代码,不再复制了

提示:要将代码中的端口和ip换成自己的,如何在控制台搜索能用的ip和端口自己去搜。

运行时要将裁判的代码先运行,出现server waiting说明是正确的,再重新打开控制台打开选手1的,再重新打开一个打开选手2的,等待一会就会出现结果

实验结果:

要将经典的“石头剪刀”游戏从本地Linux环境转换为网络运行,我们需要做以下几个步骤: 1. **选择通信机制**:由于需要网络支持,我们可以选择Socket编程作为基础的IPC(进程通信)。Socket提供了一种标准的网络通信协议,使得应用程序能够相互通信。 2. **服务器端设计**:创建一个服务器端程序,它监听客户端的连接请求。当客户端连接后,服务器会发送游戏规则的信息,并接收客户端的选择。服务器负责管理游戏流程并判定胜负。 ```c #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <arpa/inet.h> // 简化的客户端-服务器通信结构 typedef struct { int server_sock; // 服务器套接字 char client_ip[INET_ADDRSTRLEN]; // 客户端IP地址 } ClientConnection; void* game_server(void* arg) { // ... 实现服务器端逻辑 ... } int main() { // 创建服务器套接字 ServerConnection server; if (socket(server.server_sock, SOCK_STREAM, 0) == -1) { perror("Error creating socket"); return 1; } // ... 绑定地址、监听等设置 ... // 启动服务器线程处理客户端连接 pthread_t server_thread; pthread_create(&server_thread, NULL, game_server, &server); // 等待客户端连接... } ``` 3. **客户端设计**:客户端也需要创建一个Socket连接到服务器,发送游戏选择,然后接收服务器的反馈。客户端可以是一个独立的应用程序,也可以是一个网页嵌入的游戏模块。 4. **数据序列化**:为了在网络上传输游戏状态和玩家选择,可能需要对数据进行序列化,如JSON或二进制格式。这一步骤用于编码游戏信息以便于跨平台传输。 5. **游戏逻辑**:在服务器和客户端上,都需要包含相同的“石头剪刀”游戏逻辑,只是交互的方式不同。 6. **错误处理和安全性**:确保在整个过程中处理可能出现的连接断开、数据解析错误等问题,并考虑添加基本的安全措施,例如验证用户输入和保护敏感信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值