fread吊,C ++与管道

时间:2014-11-25 03:17:50

标签: c++ file-io pipe

我正在编写一个tictactoe应用程序,它在服务器和客户端文件之间进行通信。目前,我的程序在尝试阅读玩家移动时挂起。客户端显示成功写入管道但服务器未读取信息。任何帮助,将不胜感激。下面是两部分的违规代码。编辑:我刚刚意识到格式化在复制/粘贴中完全错误,对不起。

客户端main():

//used to define int holder for server read in
const int MAX = 2;
//used to define buffers to transfer information
const int BUFFERS = 10;
//path of the global pipe
const string PRIMARY = "/home/mking/GPipe";

int main() {

    //variables
    size_t result;
    srand(time(NULL) );
  int s = rand() % 10000;
    if (s < 1000) { s += 1000; }
    cout << s << endl;
  string userWrite = "/temp/" + to_string(s);
  s = rand() % 10000;
    if (s < 1000) { s += 1000; }
    cout << s << endl;
  string serverWrite = "/temp/" + to_string(s);

    cout << PRIMARY << endl;

    cout << "User pipe is " << userWrite << endl;
    cout << "Server pipe is " << serverWrite << endl;

    // send personal pipe information through global pipe to server
  FILE * comms = fopen(PRIMARY.c_str(), "w");
    cout << "Comms open" << endl;

  result = fwrite(userWrite.c_str(), 1, userWrite.length(), comms);
    if (result < userWrite.length()) { cout << endl << endl << endl << endl << endl << "write error, userfifo" << endl; }

  result = fwrite(serverWrite.c_str(), 1, serverWrite.length(), comms);
    if (result < userWrite.length()) { cout << endl << endl << endl << endl << endl << "write error, serverfifo" << endl; }

    cout << "Comms written to" << endl;

    //done with comms so close it
  fclose(comms);

    // for some reason sending /tmp/ caused a hang also, so i improvised
    userWrite.erase(2,1);
    serverWrite.erase(2,1);

    // make the personal pipes
    cout << userWrite << " " << serverWrite << endl;
  mkfifo(userWrite.c_str(), 0777);
  mkfifo(serverWrite.c_str(), 0777);

    // open the personal pipes with read or write privelege
    cout << "fifos made" << endl;
    FILE * pwrite = fopen(userWrite.c_str(), "w");
    cout << "pwrite open" << endl;
    FILE * pread = fopen(serverWrite.c_str(), "r");
    cout << "pread open" << endl;

    // if either pipe did not get made correctly, print an error
    if (pwrite == NULL ) { cout << "pwrite is wrong" << endl; }
    if (pread == NULL ) { cout << "pread is wrong" << endl; }

    // used to transfer information between pipes
  string buffer = "/temp/0000";
  string catcher = "/temp/0000";

    // initialize curses functions
    initscr();
  noecho();
    keypad(stdscr,TRUE);
    cbreak();
  WINDOW * screen = newwin(LINES/2, COLS/2, 0, 0);
    wclear(screen);
    keypad(screen,TRUE);

    //wait for input before playing the game
    int c = getch();
  displayOpening(screen);
  c = getch();

    //initialize the game data types
  int row = 0;
  int column = 0; 
  vector<pair<int, int> > userMoves;
  vector<pair<int,int> > serverMoves;
    int charInt[MAX];
    bool invalid = 0;

    //until game is over or user exits
  while (1) {
        // update the board
    displayBoard(screen,userMoves,serverMoves, row, column, invalid);

        // based on user input, do stuff, supports wsad or arrow keys
    switch(c = getch() ) {

        // if go up, move up a row or go back to bottom if at top
    case KEY_UP:
        case 'w':
      if (row == 0) { row = 2; }
      else { row--; }
      break;

        // if go down, move down a row or go back to the top if at bottom
    case KEY_DOWN:
        case 's':
      if (row == 2) { row = 0; }
      else { row++; }
      break;

        // if go left, move left a column or go back to the far right if at far left 
    case KEY_LEFT:
        case 'a':
      if (column == 0) { column = 2; }
      else { column--; }
      break;

        // if go right, move right a column or go back to the far left if at far right
    case KEY_RIGHT:
        case 'd':
      if (column == 2) { column = 0; }
      else { column++; }
      break;

        // if spacebar is pressed, enter move if valid, otherwise tell invalid and get more input
    case ' ':
      if (checkX(row, column, userMoves, serverMoves)) {
                invalid = 0;

                // no longer used function, thought maybe was the issue
                //addX(row,column,userMoves,buffer);

                //catch information in buffer to send to server
                buffer[8] = (row + '0');
                buffer[9] = (column + '0');

                //cout << "buffer 0 and 1 are " << int(buffer[0]) << " " << int(buffer[1]) << endl; 
                // add newest move to the list of user moves
                userMoves.push_back(make_pair(row,column));

                // check if the game is over, send a game over message to server if so and exit/clean up pipes
                if (checkValid(userMoves,serverMoves) == 0 || (userMoves.size() + serverMoves.size() == 9) ) {
                    youwin(screen);
                    buffer[8] = (3 + '0');
                    buffer[9] = (3 + '0');
                    result = fwrite(buffer.c_str(), 1, buffer.length(), pwrite);
                    if (result < BUFFERS) { cout << endl << endl << endl << endl << endl << "write error, usermove" << endl; }
                    fclose(pread);
                    fclose(pwrite);
                    unlink(userWrite.c_str());
                    unlink(serverWrite.c_str());
                    endwin();
                    return 0;
                }

                //mvwaddch(screen, 12, 1, 'k');
                //wrefresh(screen);

                //cout << endl << endl << endl << endl << endl << buffer << " " << buffer.length() << endl;

                // write newest move to server, currently where hangs!!!!!!
                result = fwrite(buffer.c_str(),1,buffer.length(),pwrite);
                if (result < BUFFERS) { cout << endl << endl << endl << endl << endl << "write error, usermove" << endl; }
                //cout << endl << "written successfully" << endl;

                //mvwaddch(screen,12,1,'l');
                //wrefresh(screen);

                // read in server counter move
                result = fread(&catcher[0],1,BUFFERS,pread);
                if (result < BUFFERS) { cout << endl << endl << endl << endl << endl << "read error, servermove" << endl; }

                // catch newest computer move
                charInt[0] = (catcher[8] - '0');
                charInt[1] = (catcher[9] - '0');

                // if the server says it won, clean up pipes and exit
                if (charInt[0] == 3 && charInt[1] == 3) {
                    youlose(screen);
                    fclose(pread);
                    fclose(pwrite);
                    unlink(userWrite.c_str());
                    unlink(serverWrite.c_str());
                    endwin();
                    return 0;
                }

                // check if the server made a valid move
                if (checkX(charInt[0], charInt[1], userMoves, serverMoves)) { invalid = 1; }

                //addX(charInt[0],charInt[1],serverMoves,catcher);

                // add newest server move to list of server moves
                serverMoves.push_back(make_pair(charInt[0],charInt[1]));

                // if server has won or a draw, tell the server and clean up pipes/exit
                if (checkValid(userMoves,serverMoves) == 0) {
                    youlose(screen);
                    buffer[8] = (3 + '0');
                    buffer[9] = (3 + '0');
                    result = fwrite(&buffer[0],1,BUFFERS,pwrite);
                    if (result < BUFFERS) { cout << endl << endl << endl << endl << endl << "write error, usermove" << endl; }
                    fclose(pread);
                    fclose(pwrite);
                    unlink(userWrite.c_str());
                    unlink(serverWrite.c_str());
                    endwin();
                    return 0;
                }

      }

            // if the move was invalid say so
      else { invalid = 1; }
      break;

        // if user wants to exit, tell the server and clean up/exit
    case 'q':
            buffer[8] = 3 + '0';
            buffer[9] = 3 + '0';
            result = fwrite(&buffer[0],sizeof(char),BUFFERS,pwrite);
            if (result < BUFFERS) { cout << endl << endl << endl << endl << endl << "write error, usermove" << endl; }
      fclose(pread);
      fclose(pwrite);
            unlink(userWrite.c_str());
            unlink(serverWrite.c_str());
            endwin();
      return 0;
      break;
    default:
      break;
    }

  }

  return 0;
}

server main():

const int GRID = 9;
const int MAX_G = 10;
const int MAX_L = 10;
const string PRIMARY="/home/mking/GPipe";

int main() {

    // variables to hold personal pipe input
  char userWrite[MAX_L];
  char serverWrite[MAX_L];


    // open global pipe and prepare for input
    cout << PRIMARY << endl;
  FILE * comms = fopen(PRIMARY.c_str(), "r");
    cout << "comms open" << endl;
  pid_t pid;
  bool valid = 1;
    int charInt[MAX_G];
    char prev[] = "/temp/0000";
    size_t result;

    // run until forced to close
  while(1) {

        // get the personal pipe names

        //cout << "about to read user" << endl;
    result = fread(&userWrite[0], sizeof(char),MAX_L,comms);
        if (result < MAX_L && result > 0) { cout << "read error, user" << endl; }
        //cout << "read user" << endl;
    result = fread(&serverWrite[0], sizeof(char), MAX_L,comms);
        if (result < MAX_L && result > 0) { cout << "read error, server" << endl; }
        //cout << "read server" << endl;
        //cout << "User pipe is " << userWrite << endl;
        //cout << "Server pipe is " << serverWrite << endl;

        // if a new pipe was detected, fork and play against a client
        if (strcmp(prev, userWrite) != 0) { pid = fork(); }
        strcpy(prev, userWrite);

        // if a chiled, play against a client
    if (pid == 0) {

            //close comms and open personal pipes
            cout << "In child" << endl;
      fclose(comms);

            string user(userWrite);
            string server(serverWrite);

            // was having issues with fread earlier also, roundabout fix
            user.erase(2,1);
            server.erase(2,1);

            // set up pipes
            cout << "opened pipes " << user << " " << server << endl;
      FILE * userFifo = fopen(user.c_str(), "r");
            cout << "opened user pipe" << endl;
      FILE * serverFifo = fopen(server.c_str(), "w");
            cout << "opened server pipe" << endl;

            // set up data for server to check moves
      pair<int,int> move;
      vector<pair<int,int> > userMoves;
      vector<pair<int,int> > serverMoves;

      char buffer[MAX_G] = {'/','t','e','m','p','/','0','0' };
      char filler[MAX_G];
      vector<bool> untaken (GRID, 1);

            // while game not over
      while (valid) {
                // get a new move, HANGS HERE!!!!!

                cout << "waiting for user move" << endl;
                result = fread(&filler[0], sizeof(char), MAX_G, userFifo);
                if (result < MAX_G) { cout << "read error, usermove" << endl; }
                cout << "move read in" << endl;

                // catch user move
                charInt[0] = filler[6] - '0';
                charInt[1] = filler[7] - '0';
                cout << charInt[0] << " " << charInt[1] << endl;

                // if user says game over, close pipes
                if (charInt[0] == 3 && charInt[1] == 3) {
                    fclose(userFifo);
                    fclose(serverFifo);
                    exit(0);
                }

                // add user move to list of moves
                userMoves.push_back(make_pair(charInt[0], charInt[1]));

                // mark location of taken moves
                untaken[(userMoves.back().first * 3 + userMoves.back().second)] = 0;

                // see if game can be ended and add a server move
                valid = checkX(userMoves,serverMoves, untaken);
                untaken[(serverMoves.back().first * 3 + serverMoves.back().second)] = 0;

                //prepare server move for writing
            buffer[6] = serverMoves.back().first + '0';
                buffer[7] = serverMoves.back().second + '0';

                //buffer[0] = -1;
                //buffer[1] = -1;

                // write servermove to client
                //cout << buffer[0] << " " << buffer[1] << endl;
                result = fwrite(&buffer[0],sizeof(char),MAX_G,serverFifo);
                if (result < MAX_G) { cout << "write error, servermove" << endl; }
      }

            // close pipes if game is over
      fclose(userFifo);
      fclose(serverFifo);
      exit(0);
    }

  }
  fclose(comms);

  return 0;
}

0 个答案:

没有答案