C和C++中的简单echo客户端服务器
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
如何修复它以使其按我的意愿工作?要制作一个真正的多线程echo服务器客户端应用程序?
这是我的代码:
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, "%sn", 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 closedn");
break;
}
buffer[bytes_read] = ' ';
if (strcmp("\q",buffer)==0)
{
fprintf(stdout, "Server OFF.n");
break;
}
fprintf(stdout, "From client: %sn", buffer);
if ((write(server2client,buffer, strlen(buffer)))== -1)
{
perror("write");
break;
}
fprintf(stdout, "Send to client: %sn", 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: %sn",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将其自身表示为文件系统中的命名条目。
为了区分这些连接通道的实例,它们的标识名称需要不同。在您的代码中,它们不是。每个cleint使用相同的fifo与服务器和verse vica通信。
更改您的代码,使每个客户端的fifos文件系统条目的名称不同。
想想它是如何使用套接字工作的:
- 服务器端有一个侦听套接字接受所有客户端连接
- 接受连接的结果是为一个特定客户端设置特定套接字(允许双工通信)
要使用fifos替换它,需要:
- 一个替换监听插座
- 替换为每个客户端连接服务的每个套接字
相关文章:
- "unknown ca"自生成的 CA、证书和客户端/服务器
- 如何将函数集合传递给客户端类,以便将它们当作客户端类本身的成员使用
- 使用调试/崩溃报告将应用程序部署到客户端
- 如何在本地机器上运行c++和javascript客户端代码(hackerbank风格)
- 如何通过套接字将文本文件的内容从服务器发送到客户端
- 从服务器传输到客户端的消息不会出现
- OpenSSL TLS服务器-使用客户端证书白名单
- 当服务中的事件被触发时,如何将响应从服务发送回客户端?
- 我可以与 python 服务器而不是 c++ 客户端建立 tcp/ip 套接字吗?
- 提升 Asio TCP 服务器 处理多个客户端
- boost::asio UDP 广播客户端仅接收"fast"数据包
- 如何绑定 C++ gRPC 客户端的网络接口
- C++套接字客户端到 Python 服务器未创建连接
- 用于解析 win64 堆栈跟踪的命令行客户端(可以访问符号服务器)
- 将相机数据从服务器实时流式传输到客户端
- 如何将 Firebase 与基于 Linux 的客户端应用配合使用,以便与服务器进行双向消息通信
- GRPC C++ TLS 客户端 grpc::SslCredentials() 方法不返回
- C和C++中的简单echo客户端服务器
- 使用Echo客户端示例从Qt UI连接到WebSocket服务器
- Qt/C++echo客户端+python echo服务器存在问题(未收到数据)