gpt4 book ai didi

c - 如何仅在前一个命令在使用套接字的服务器/客户端程序中完成后才执行命令

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:42:42 25 4
gpt4 key购买 nike

我正在使用套接字用 C 编写一个客户端/服务器程序。服务器必须能够处理许多客户端。

服务器正确设置后,客户端连接到它,并发送“Ready”或“Kill”。服务器收到消息,回复“Go”或“Destroy”。

如果客户端收到的回复是“Go”,那么它会执行一个传入参数的命令。该命令是这样执行的:system(command)

如果客户端收到的回复是“Destroy”,则关闭Client,同时销毁服务器。

服务器必须能够处理许多客户端,但它必须允许一次只允许一个客户端执行一条命令。此外,如果客户端连接到服务器并发送“Kill”,则必须关闭队列中的所有客户端,并且必须立即销毁服务器。

因此,为了实现这一点,我正在使用 select()

所以我对这个规范有疑问:它必须只允许一个客户端一次执行一条命令。

基本上,命令是在客户端执行的。而且我不希望两个客户端能够同时执行一个命令。

这是一个例子(这不是代码):

Client1 : system(echosleep hello1 goodbye1);

Client2 : system(echosleep hello2 goodbye2);

所以我的程序现在的工作方式是打印:

hello1
hello2
goodbye1
goodbye2

但我想要的是:

hello1
goodbye1
hello2
goodbye2

--> 而且我不明白服务器如何知道命令是否完成,因为它是在客户端执行的。

所以这是我的服务器代码结构(我没有在这里发布完整的代码,因为我的问题不是关于编写代码本身,而是更多关于结构,以及我应该将“Go”发送到客户端的确切位置.. . 所以我省略了不相关的代码):

//initialize all client_socket[] to 0
//Create master_socket
//bind() master_socket
//listen() master_socket

//accept the incoming connection
addrlen = sizeof(address);

while(TRUE) {
//clear the socket set
FD_ZERO(&readfds);

//add master socket to set
FD_SET(master_socket, &readfds);
max_sd = master_socket;

//add child sockets to set
for ( i = 0 ; i < max_clients ; i++) {
//socket descriptor
sd = client_socket[i];

//if valid socket descriptor then add to read list
if(sd > 0) {
FD_SET( sd , &readfds);
}

//highest file descriptor number, need it for the select function
if(sd > max_sd) {
max_sd = sd;
}
}

//wait for an activity on one of the sockets , timeout is NULL , so wait indefinitely
activity = select( max_sd + 1 , &readfds , NULL , NULL , NULL);

if (activity < 0) {
printf("select()");
}

//If something happened on the master socket , then its an incoming connection
if (FD_ISSET(master_socket, &readfds)) {
if ((new_socket = accept(master_socket, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0) {
perror("accept()");
return -1;
}

//Check message received from the Client
//if message == Kill then destroy everything (this is working)

//if message == Ready, then send Go
//When the Client receives Go, it will proceed with the execution of his command

//add Client to the queue
for (i = 0; i < max_clients; i++) {
//if position is empty
if( client_socket[i] == 0 ) {
client_socket[i] = new_socket;
break;
}
}
}
}

最佳答案

I don't understand how the server could know if the command is finished or not

简单的答案是,它不能,正是出于您提到的原因。除非客户端告诉服务器,否则服务器无法知道客户端内部发生了什么。

因此,解决该问题的一个方法是让客户端在执行完命令后向服务器发送另一条消息(例如“完成”)。收到“完成”消息后,服务器会知道客户端已完成执行,然后可以在需要时在另一个客户端上授权另一个命令。

(顺便说一下,让客户端从网络接收一个字符串并将该字符串传递给 system() 是一个潜在的安全漏洞——“邪恶”的服务器可能传递一个类似“rm -rf *”的字符串并导致您的客户端删除它的所有文件!所以在学术环境之外运行客户端软件时要小心)

关于c - 如何仅在前一个命令在使用套接字的服务器/客户端程序中完成后才执行命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40953355/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com