我正在编写一个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;
}