Reputation: 11
I have a server-client system (concurrent server). I have different clients on different machines. I am trying to send a notification to particular clients. However, I have a problem as the clients all have the same socket descriptor. On both computers, the clients have a socket descriptor of 3 and at the server a sd of 5. Can someone please tell me how I can identify these different clients and why is this happening?
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;
}
Upvotes: 0
Views: 413
Reputation: 27542
You can get the client address & port returned to you by accept
. Currently you are passing a null
client_conn = accept(listen_fd, (struct sockaddr *) NULL, NULL);
however just add a few lines like
struct sockaddr_in serv_addr, cli_addr;
int len = sizeof(cli_addr);
client_conn = accept(listen_fd, (struct sockaddr *) &cli_addr, &len);
and you have the client info in cli_addr.sin_addr.s_addr and cli_addr.sin_port.
You can get the pid of the child processing the connection from the return code of fork. That should give you all the information you need to create a table.
Upvotes: 0
Reputation: 780879
After the server forks a child it does close(client_conn)
. When accept
assigns a socket descriptor to the new connection, it uses the lowest closed descriptor. Since you closed the socket earlier, it can be used for the next client that comes in.
This isn't a problem, because the connections are being managed by the child processes. They each have their own descriptor 5
, and they don't interfere with each other.
Upvotes: 1