Is it possible that a TCP server program can listen on two different socket interface?
Problem Statement:
I've a problem statement where the TCP server will be having two interfaces:
- Interface I: For accepting generic data from TCP client (IP address 192.168.5.10:2000)
- Interface II: Management Interface for the server (IP address 192.168.5.11:2000)
Interface I: This interface shall receive data from TCP client, processes them & send it back to client.
Interface II: This interface shall receive commands (meant for Servers management purpose). This commands most probably would be sent through telnet.
Current Status:
I already have a thread based TCP server program where I've "Interface I" up & running(I'm able to receive data from multiple clients, process them & send it back)
Can anyone give me some pointers/prototype example on how to add "Interface II" to my TCP server program?
NOTE: TCP server program is written in C programming language for Linux OS
UPDATE
Below is the code fragment I've written so far for listening on one socket. I tried modifying it for listening over two sockets as you've directed but I'm facing trouble while trying to spawn a different thread for the other socket interface. Will it possible for you to modify this to listen on two sockets? It would be really helpful.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
void *data_processing_thread(void *arg);
int main(int argc, char **argv)
{
int fdmax, listener, newfd, res;
int optval=1;
socklen_t addrlen;
int server_port = 4000;
/* master, temp file descriptor list */
fd_set *master, *read_fds;
/* client, server address */
struct sockaddr_in server_addr, client_addr;
pthread_t thread;
master = malloc(sizeof(fd_set));
read_fds = malloc(sizeof(fd_set));
FD_ZERO(master);
FD_ZERO(read_fds);
/* create endpoint for communication */
if ((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("failed to create listener\n");
return -1;
}
/* check if address is already in use? */
if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &optval,
sizeof(int)) == -1) {
perror("socket address already in use!\n");
return -1;
}
/* bind */
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(server_port);
memset(&(server_addr.sin_zero), '\0', 8);
if (bind(listener, (struct sockaddr*)&server_addr,
sizeof(server_addr)) == -1) {
perror("failed to do the bind\n");
return -1;
}
/* listen for connect on sockets */
if (listen(listener, 10) == -1) {
perror("failed to listen on socket\n");
return -1;
}
/* add the listener to the master set */
FD_SET(listener, master);
/* keep track of biggest file descriptor */
fdmax = listener;
while (1) {
read_fds = master;
/* wait till socket descriptor is ready for the operation */
if (select(fdmax+1, read_fds, NULL, NULL, NULL) == -1) {
perror("failed to do select() on socket\n");
return -1;
}
/* Run through existing data connections looking for data to be
* read */
int cnt;
int *accept_fd = 0;
for (cnt=0; cnt<=fdmax; cnt++) {
if (cnt == listener) {
if (FD_ISSET(cnt, read_fds)) {
addrlen = sizeof(client_addr);
if ((newfd = accept(listener, (struct sockaddr*)&client_addr, &addrlen)) == -1) {
perror("failed to accept incoming connection\n");
} else {
fprintf(stdout, "Server: Connection from client [%s] on socket [%d]\n",
inet_ntoa(client_addr.sin_addr), newfd);
accept_fd = malloc(sizeof(int));
*accept_fd = newfd;
if ((res = pthread_create(&thread, NULL, data_processing_thread, (void*)accept_fd)) != 0) {
perror("Thread creation failed\n");
free(accept_fd);
}
}
}
continue;
}
}
}
return 1;
}
void *data_processing_thread(void *arg)
{
int nbytes;
int *recv_fd = (int*)arg;
char *buffer = malloc(sizeof(char)*256);
while(1) {
fprintf(stdout, "Server: Waiting for data from socket fd %d\n", *recv_fd);
/* receive incoming data from comm client */
if ((nbytes = recv(*recv_fd, buffer, sizeof(buffer), 0)) <= 0) {
if (nbytes != 0) {
perror("failed to receive\n");
}
break;
} else {
fprintf(stdout, "Data received: %s\n", buffer);
}
}
close(*recv_fd);
free(recv_fd);
pthread_exit(0);
}