[英]Simple echo client-server in C and C++
我想使用命名管道編寫一個echo客戶-服務器應用程序(我用套接字完成了它,它可以工作,但是現在我想對命名管道做同樣的事情。)服務器必須是多線程的。
我以為我的程序在我第一次運行時就可以運行,一切都很好。 連接到服務器的每個客戶端都會收到一條消息。
但是現在,當我第二次嘗試運行程序時,仍然收到此消息:
mkfifo client2server: File exists
(許多此類消息)。 這是我嘗試運行./echoserver時的輸出:
$ ./echoserver
Server is working ...
mkfifo client2server: File exists
mkfifo client2server: File exists
mkfifo client2server: File exists
mkfifo client2server: File exists
mkfifo client2server: File exists
mkfifo client2server: File exists
mkfifo client2server: File exists
mkfifo client2server: File exists
mkfifo client2server: File exists
mkfifo client2server: File exists
mkfifo client2server: File exists
mkfifo client2server: File exists
如何使其按我的意願工作? 要制作真正的多線程回顯服務器-客戶端應用程序?
這是我的代碼:
echoserver.cpp
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <string>
#include <sstream>
using namespace std;
string toString(int d)
{
ostringstream ss;
ss << d;
return ss.str();
}
void* clients_service(void * arg)
{
int client_id = *((int*)&arg), server2client = -1, buffsize = 255, bytes_read = -1, client2server = -1;
client_id++;
char buffer[255];
string fifoname = "/tmp/server2client";
fifoname += toString(client_id);
string fifoclient = "/tmp/client2server";
fifoclient += toString(client_id);
if(mkfifo(fifoclient.c_str(), 0666) == -1)
{
perror("mkfifo client2server");
fprintf(stderr, "%s\n", strerror(errno));
exit(1);
}
if((client2server = open(fifoclient.c_str(), O_RDONLY)) == -1)
{
perror("open client2server");
exit(1);
}
if(mkfifo(fifoname.c_str(), 0666) == -1)
{
perror("mkfifo server2client");
exit(1);
}
if((server2client = open(fifoname.c_str(), O_WRONLY)) == -1)
{
perror("open server2client");
exit(1);
}
for(;;)
{
if ((bytes_read = read(client2server, buffer, buffsize))== -1)
{
perror("read");
exit(1);
}
else if (bytes_read == 0)
{
fprintf(stdout, "Connection closed\n");
break;
}
buffer[bytes_read] = '\0';
if (strcmp("\\q",buffer)==0)
{
fprintf(stdout, "Server OFF.\n");
break;
}
fprintf(stdout, "From client: %s\n", buffer);
if ((write(server2client,buffer, strlen(buffer)))== -1)
{
perror("write");
break;
}
fprintf(stdout, "Send to client: %s\n", buffer);
// clean buffer from any data
memset(buffer, 0, sizeof(buffer));
}
close(client2server);
close(server2client);
unlink(fifoname.c_str());
unlink(fifoclient.c_str());
}
int main(int argc, char **argv)
{
int clientsCounter = 0;
fprintf(stdout, "Server is working ...\n");
while (1)
{
pthread_t thread;
pthread_create(&thread, NULL, clients_service, (void*)&clientsCounter);
}
return 0;
}
像這樣編譯它: g++ -Wall -pthread echoserver.cpp -o echoserver
echoclient.c
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
int client_to_server;
char *myfifo = "/tmp/client2server";
int server_to_client;
char *myfifo2 = "/tmp/server2client";
char str[255];
/* write str to the FIFO */
client_to_server = open(myfifo, O_WRONLY);
server_to_client = open(myfifo2, O_RDONLY);
while(1)
{
printf("\n> ");
scanf("%s", str);
write(client_to_server, str, sizeof(str));
read(server_to_client,str,sizeof(str));
printf("From server: %s\n",str);
}
close(client_to_server);
close(server_to_client);
/* remove the FIFO */
unlink("/tmp/server2client");
unlink("/tmp/client2server");
return 0;
}
像這樣編譯它: gcc echoclient.c -o echoclient
要設置多個連接,您需要一個連接的多個獨立實例。 連接的實例由fifo表示,該fifo在文件系統中將自身表示為命名條目。
為了區分連接通道的那些實例,它們的標識名稱需要不同。 在您的代碼中不是。 每個部門都使用相同的fifo與服務器和vica通信。
更改您的代碼,以使每個客戶的fifos文件系統條目的名稱都不同。
考慮一下它如何使用套接字工作:
要使用fifos替換此代碼,需要:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.