【发布时间】:2016-12-03 22:48:33
【问题描述】:
我正在使用套接字在 C 中制作客户端/服务器程序。服务器必须能够处理许多客户端。
服务器正确设置后,客户端连接到它,并发送“Ready”或“Kill”。服务器收到消息,回复“Go”或“Destroy”。
如果客户端收到的回复是“Go”,那么它执行一个传入参数的命令。该命令的执行方式如下:system(command)
如果客户端收到的回复是“Destroy”,则关闭客户端,销毁服务器。
服务器必须能够处理许多客户端,但它必须允许一次只允许一个客户端执行命令。另外,如果有客户端连接到服务器并发送“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;
}
}
}
}
【问题讨论】:
标签: c linux sockets select server