我正在使用 C 语言编写服务器代码,该代码必须只接受少量客户端,如果有额外的客户端到达,服务器将使该客户端等待,直到其中一个旧客户端终止。
例如 (服务器只能接受10个客户端,如果有新客户端到达,服务器将让该客户端等待,直到10个客户端之一终止,然后才能为他提供服务)。
我知道我必须在 listen()
函数之后和 accept()
之前使用 signal()
函数,并创建一个值统计客户端数量,但不知道如何正确使用。
任何人都可以给我一个提示或简单的例子吗?
谢谢,,,,,,
最佳答案
无需使用signal()
。示例:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
main()
{
int s = socket(PF_INET, SOCK_STREAM, 0); // server socket
if (s == -1) return perror("socket"), 1;
if (listen(s, 0) == -1) return perror("listen"), 1;
const int n = 10; // number of clients allowed to be served
fd_set fds, rfds;
FD_ZERO(&fds);
FD_SET(s, &fds); // initially, set of sockets holds server
int nfds = s+1, fd, clients = 0;
while (rfds = fds, select(nfds, &rfds, NULL, NULL, NULL) > 0)
for (fd = 0; fd < nfds; ++fd)
if (FD_ISSET(fd, &rfds)) // see which sockets of set are ready
if (fd == s) // is it the server socket?
{ // yes, so it is a client's connection request
printf("new client request ");
struct sockaddr_in sa = { AF_INET, 0, INADDR_ANY };
socklen_t sal = sizeof sa;
int c = accept(s, (struct sockaddr *)&sa, &sal);
if (c == -1) return perror("accept"), 1;
FD_SET(c, &fds); if (nfds <= c) nfds = c+1; // add client
printf("accepted (fd=%d) # clients now %d\n", c, ++clients);
if (clients == n) // allowed number hit?
puts("Further client requests will be ignored."),
FD_CLR(s, &fds); // don't watch server now
}
else
{ // this is a client's message or termination
printf("client fd=%d: ", fd);
char buf[BUFSIZ];
size_t count = read(fd, buf, sizeof buf);
if (count > 0) fwrite(buf, 1, count, stdout);
else
{ // no more data from client, so close the connection
close(fd);
FD_CLR(fd, &fds); // remove client from watch set
printf("closed, # clients now %d\n", --clients);
if (clients == n-1) // went just below allowed number?
FD_SET(s, &fds), // watch server again
puts("New client requests will be accepted again.");
}
}
return perror("select"), 1;
}
注意:该程序绑定(bind)到一个随机的空闲端口,您可以使用 e 找到该端口。 G。 netstat -tlp
。当然,您也可以bind()
到特定的地址和端口。无论如何你都可以用 e 来测试它。 G。 nc 主机名端口
。
关于c - 服务器只能接受n个客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26928407/