I was given an example of how it should work :
client 123.123.123.123 5050
(client connects to server running at IP 123.123.123.123, port 5050)
$ Client connected, please enter command to send:
ls -l | grep -e 'something'
$ Server returned:
...
Here are the client respectively the server codes. How can I make the server to supporting any number of client connections, (multi-threaded server as far as I know)? Appreciate any code suggestions or other specifications, thank you.
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <pthread.h> void error(const char *msg) { perror(msg); exit(0); } int main(int argc, char *argv[]) { int sockfd, portno, n; struct sockaddr_in serv_addr; struct hostent *server; char buffer[256]; if (argc < 3) { fprintf(stderr,"usage %s hostname port\n", argv[0]); exit(0); } portno = atoi(argv[2]); sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) error("ERROR opening socket"); server = gethostbyname(argv[1]); if (server == NULL) { fprintf(stderr,"ERROR, no such host\n"); exit(0); } bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length); serv_addr.sin_port = htons(portno); if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) error("ERROR connecting"); bzero(buffer,256); int doExit = 1; while(doExit) { printf("Enter message:"); fgets(buffer, 255, stdin); buffer[strlen(buffer)-1] = '\0'; doExit = strcmp(buffer, "exit"); n = strlen(buffer); write(sockfd, &n, sizeof(int)); write(sockfd, buffer, n); read(sockfd, &n, sizeof(int)); read(sockfd, buffer, n); buffer[n] = '\0'; printf("Response: %s\n", buffer); } // n = read(sockfd,buffer,255); if (n < 0) error("ERROR reading from socket"); printf("%s\n",buffer); close(sockfd); return 0; }And the server,
/* A simple server in the internet domain using TCP The port number is passed as an argument */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <pthread.h> int sockfd, newsockfd[11], portno; socklen_t clilen; char buffer[2560]; struct sockaddr_in serv_addr, cli_addr; int n; void error(const char *msg) { perror(msg); exit(1); } void execution(char *command) { //command[strlen(command)-1] = '\0'; //printf(">"); char **arguments; char *cuv; int k = 0; arguments = (char**)malloc(sizeof(char)*50); cuv = strtok(command, " "); arguments[k] = malloc(strlen(cuv)*sizeof(char)); if(arguments[k] != NULL) { strcpy(arguments[k],cuv); k++; } while(cuv) { cuv = strtok(NULL," "); if(cuv == NULL) arguments[k] = NULL; else arguments[k] = malloc(strlen(cuv)*sizeof(char)); if(arguments[k] != NULL) { strcpy(arguments[k],cuv); k++; } } //int n = fork(); //if(n==0) { execvp(arguments[0],arguments); //} //printf(">"); } void *start(void *arg) { int i = *((int*)arg); newsockfd[i] = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); if (newsockfd[i] < 0) error("ERROR on accept"); bzero(buffer,2560); int doExit = 1; int fd[2]; int status; while(doExit) { if(pipe(fd)<0) { printf("Eroare la crearea pipe-ului\n"); exit(1); } //n = read(newsockfd[i],buffer,255); read(newsockfd[i], &n, sizeof(int)); read(newsockfd[i], buffer, n); buffer[n] = '\0'; doExit = strcmp(buffer, "exit"); int pid=fork(); if(pid==0){ close(fd[0]); dup2(fd[1],1); //close(fd[1]); //execlp("dir","dir",NULL); execution(buffer); } // printf("Received: %s\n", buffer); /*strcpy(buffer, "I got it!"); n = strlen(buffer); write(newsockfd[i], &n, sizeof(int)); write(newsockfd[i], buffer, n);*/ else{ //wait(&status); close(fd[1]); wait(&status); while((n=read(fd[0],buffer,2559))>0){ buffer[n] = '\0'; // printf("%s",buffer); write(newsockfd[i], &n, sizeof(int)); write(newsockfd[i], buffer, n); } close(fd[0]); } //printf("Received: %s\n", buffer); //strcpy(buffer, "I got it!"); //n = strlen(buffer); //write(newsockfd[i], &n, sizeof(int)); //write(newsockfd[i], buffer, n); } close(newsockfd[i]); } int main(int argc, char *argv[]) { pthread_t threads[10]; if (argc < 2) { fprintf(stderr,"ERROR, no port provided\n"); exit(1); } sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) error("ERROR opening socket"); bzero((char *) &serv_addr, sizeof(serv_addr)); portno = atoi(argv[1]); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) error("ERROR on binding"); listen(sockfd,5); clilen = sizeof(cli_addr); int i, *p; for(i = 0; i < 10; i++) { p = (int*)malloc(sizeof(int)); *p = i; pthread_create(&threads[i], NULL, start, p); } for(i = 0; i < 10; i++) pthread_join(threads[i], NULL); close(sockfd); return 0; }