我有一个服务器 - 客户端系统(并发服务器)。我在不同的机器上有不同的客户。我正在尝试向特定客户发送通知。但是,我有一个问题,因为客户端都有相同的套接字描述符。在两台计算机上,客户端的套接字描述符为3,服务器的sd为5.有人可以告诉我如何识别这些不同的客户端,为什么会这样?
int main(int argc, char *argv[]) {
pid_t pid;
int buff_size = 1024;
char buff[buff_size];
int listen_fd, client_conn;
struct sockaddr_in serv_addr;
int server_port = 5001;
char remote_file[255];
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
if (listen_fd < 0) {
perror("Socket cannot be opened");
exit(1);
}
/*Turning off address checking in order to allow port numbers to be
reused before the TIME_WAIT. Otherwise it will not be possible to bind
in a very short time after the server has been shut down*/
int on = 1;
int status = setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR,
(const char *) &on, sizeof(on));
if (status == -1) {
perror("Failed to Reuse Address on Binding");
}
// Initialise socket structure
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY; // Accept connections from any address
serv_addr.sin_port = htons(server_port);
// Bind the host address
if (bind(listen_fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr))
< 0) {
perror("ERROR on binding");
exit(1);
}
// Start listening for the clients, here process will
// go in sleep mode and will wait for the incoming connection
listen(listen_fd, 5);
while (1) {
//Accepting client connection
client_conn = accept(listen_fd, (struct sockaddr *) NULL, NULL);
if (client_conn < 0) {
perror("Client was not accepted...");
exit(1);
}
if ((pid = fork()) == 0) {
close(listen_fd);
bzero(buff, buff_size);
while ((bytes_read = read(client_conn, buff, buff_size)) > 0) {
fclose(file);
}
}
//Terminating child process and closing socket
close(client_conn);
exit(0);
bzero(buff, buff_size);
}
//parent process closing socket connection
close(client_conn);
}
return 0;
}
答案 0 :(得分:1)
服务器分叉后,它会close(client_conn)
。当accept
为新连接分配套接字描述符时,它使用最低的闭合描述符。由于您之前关闭了套接字,因此可以将其用于下一个进入的客户端。
这不是问题,因为连接由子进程管理。它们每个都有自己的描述符5
,它们不会相互干扰。
答案 1 :(得分:0)
您可以获取客户地址&amp;端口由accept
返回给您。目前您传递的是空值
client_conn = accept(listen_fd,(struct sockaddr *)NULL,NULL);
然而,只需添加几行,如
struct sockaddr_in serv_addr, cli_addr;
int len = sizeof(cli_addr);
client_conn = accept(listen_fd, (struct sockaddr *) &cli_addr, &len);
您在cli_addr.sin_addr.s_addr和cli_addr.sin_port中拥有客户信息。
您可以从fork的返回码获取处理连接的子进程的pid。这应该为您提供创建表格所需的所有信息。