我只想用命名管道編寫一個簡單的多客戶端服務器。我在服務器端遇到問題。當我只讀書時,一切都很好。現在,我添加了一個服務器發送消息回客戶端的可能性 - 現在它不工作...命名管道,選擇錯誤的文件描述符C++
繼承人我的服務器代碼(注意,當我刪除註釋行/ * * /,它從所有客戶讀取,它工作得很好,但 - 只讀)。如何強制服務器寫入所有客戶端呢? (這個概念是,客戶端首先寫入發送到服務器的客戶端fifoname服務器創建和打開此類FIFO和可以寫入,但寫入的部分仍然不想要工作...:/)
int main (int argc, char *argv[])
{
int fd_in, fd_out, j, result;
char buffer[4096];
const char *myfifo = "./fifo";
mkfifo(myfifo, 0666);
if ((fd_in = open(myfifo, O_RDONLY | O_NONBLOCK)) < 0)
perror(myfifo);
printf("Server reads from: %s\n", myfifo);
for (;;) {
fd_set fds_r;
fd_set master;
FD_ZERO (&fds_r);
FD_ZERO (&master);
FD_SET (fd_in, &fds_r);
master = fds_r;
if ((result = select(fd_in + 1, &fds_r, NULL, NULL, NULL)) < 0)
perror ("select()");
if (! FD_ISSET(fd_in, &fds_r))
continue;
result = read(fd_in, buffer, 4096);
printf("FROM CLIENT: %s\n", buffer);
/*if(startsWith(buffer, "#"))
{
// remove # from message from client
string login = removePrefix(buffer);
string fifoname = "./fifo";
fifoname += login;
printf("REGISTERED: %s\n", fifoname.c_str());
mkfifo(fifoname.c_str(), 0666);
if ((fd_out = open(fifoname.c_str(), O_WRONLY)) < 0)
perror(fifoname.c_str());
FD_SET (fd_out, &master);
}
/* for(j = 0; j <= fd_in; j++) {
// send to everyone!
if (FD_ISSET(j, &master)) {
// except the listener and ourselves
if (j != fd_out) {
if (write(j, buffer, sizeof(buffer)) == -1) {
perror("write");
}
}
}
}*/
memset(buffer, 0, sizeof(buffer));
}
fprintf (stderr, "Got EOF!\n");
close (fd_in);
return 0;
}
客戶端。 CPP
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string>
#include <string.h>
using namespace std;
int main(int argc, char **argv)
{
int client_to_server;
const char *myfifo = "./fifo";
int server_to_client;
string f = "./fifo";
string u(argv[1]);
f += u;
const char *myfifo2 = f.c_str();
char str[BUFSIZ];
/* write str to the FIFO */
client_to_server = open(myfifo, O_WRONLY);
server_to_client = open(myfifo2, O_RDONLY);
// register message #username
string reg = "#";
reg += u;
printf("Client writes to: %s\n", myfifo);
printf("Client reads from: %s\n", myfifo2);
// first write to server, he can now make a fifo called fifo+username
if(write(client_to_server, reg.c_str(), strlen(reg.c_str())) == -1)
perror("write:");
while(1)
{
printf("Input message to serwer: ");
scanf("%s", str);
if(write(client_to_server, str, sizeof(str))==-1)
perror("Write:"); //Very crude error check
if(read(server_to_client,str,sizeof(str))==-1)
perror("Read:"); // Very crude error check
printf("...received from the server: %s\n",str);
}
close(client_to_server);
close(server_to_client);
/* remove the FIFO */
return 0;
}
我的輸出:
服務器端:
$ ./SERVER
Server reads from: ./fifo
FROM CLIENT: #username
FROM CLIENT: hello
FROM CLIENT:
FROM CLIENT: ?
FROM CLIENT:
FROM CLIENT: huh
FROM CLIENT:
客戶端:
$ ./CLIENT username
Client writes to: ./fifo
Client reads from: ./fifousername
Input message to serwer: hello
Read:: Bad file descriptor
...received from the server: hello
Input message to serwer: ?
Read:: Bad file descriptor
...received from the server: ?
Input message to serwer: huh
Read:: Bad file descriptor
...received from the server: huh
Input message to serwer:
您忘了設置套接字非阻塞。這個「寫」可以永遠阻止。 (另外,如果你描述了實際的問題,這真的很有幫助,不幸的是,「它根本不工作」不是一個很好的問題描述,它是否會掛起?崩潰?) –
它可以與參數有關:O_RDONLY ,當你打開管道? – Pavenhimself
@DavidSchwartz:看到我的編輯,它解釋了我的問題 – yak