Adding history command to multiclient server program












0















I have this client and server program. I'm trying to add a history command where it displays the last 10 commands when you type "history" in the commandline, but I'm having issues with it where it won't display at all, but I'm not sure why it won't work. After I type "history" it won't display anything and I can't type any commands after which makes me have to re-launch the code be able to type unix commands in. This program works by sending unix commands such as "ls" or "date" and it will send the info from the server back to the client. It may be because my code is a little buggy, but it should still work. Any one can point me in the right direction?



Client:



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define BUFFSIZE 2048

char history[10][50];
int historyCounter = 0;

char *encryptedMessage(char command){
int i = 0;

while (command[i] != ''){
command[i] += 5;
i += 1;
}

return command;
}



int main(int argc, char *argv){
/*Created variables for socket, server address, arguement size, and a buffer*/
int clientSocket, ret, portnum;
struct sockaddr_in serverAddr;
int received = 0;
unsigned int echolen;
char buffer[BUFFSIZE];

/*If there is less than 3 arguments, print out a statement explaining to execute program
along witjh server ip and port*/
if(argc < 3){
fprintf(stderr,"usage %s <server-ip-addr> <server-port>n", argv[0]);
exit(0);
}
/*Convert port number from the commandline using atoi*/
portnum = atoi(argv[2]);

/*Create socket, and check if there is an error in the connection*/
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if(clientSocket < 0){
printf("Error in connection.n");
exit(1);
}
printf("Client Socket is created.n");
/*Memset server address*/
memset(&serverAddr, '', sizeof(serverAddr));
// memset(&buffer, '', sizeof(buffer));
// serverAddr.sin_family = AF_INET;
// serverAddr.sin_port = htons(PORT);
// serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

// bzero((char *) &serverAddr, sizeof(serverAddr));

/*Take ip address from commandline and set it into serverAddr*/
serverAddr.sin_family = AF_INET;
if(!inet_aton(argv[1], &serverAddr.sin_addr)){
fprintf(stderr, "Error invalid server IP addressn");
exit(1);
}
/*Take the port number and set it in the sin_port for connection*/
serverAddr.sin_port = htons(portnum);
/*Connect the client to the server, if less than 0, then there is an error in the connection*/
ret = connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in connection.n");
exit(1);
}
printf("Connected to server.n");
/*Initialize argument buffer*/
char s[100];
/*In the while loop we take the arguments after we connect and put them in stdin, we insert at the
end of s array*/
while(1){
int _switch = 0;
fgets(s, 100, stdin);
historyCounter++;
//s[strlen(s)-1]='';
echolen = strlen(s);
if(historyCounter < 10){
for(int i = 0; i < historyCounter; i++){
strcpy(history[i+1], history[i]);
}
}
strcpy(history[0], s);

/* send() from client, if it doesn't equal echolen then show it failed */
if(strcmp(s,"history") == 0){
_switch = 1;
int a = 0;
int b = 0;

for (int a = 0; a < historyCounter; a++){
printf("%d", historyCounter);
while(history[a][b] != ''){
printf("%c", history[a][b]);
b++;
}
b = 0;
printf("n");
}
printf("n");

}


if(_switch == 0){
if (send(clientSocket, s, echolen, 0) != echolen)
{
printf("Failed");
}

if(strcmp(s,"quit") == 0) //check if exit is typed
exit(0);
fprintf(stdout, "Message from server: ");
//fprintf(stdin, "%sn", s);
while (received < echolen)
{
ssize_t bytes = 0;
/* recv() from server, the bytes we receive are from the clientSocket */
if ((bytes = recv(clientSocket, buffer, echolen, 0)) < 1)
{
printf("Failed to get Information");
}
received += bytes;
buffer[bytes] = '';
/*WE receive the information and print in stdout what's in the buffer*/
fprintf(stdout, buffer);
}
ssize_t bytes = 0;
/*Place /0 at end of the buffer*/
do {
buffer[bytes] = '';
printf("%sn", buffer);
} while((bytes = recv(clientSocket, buffer, BUFFSIZE-1, 0))>=BUFFSIZE-1);
buffer[bytes] = '';
printf("%sn", buffer);
printf("n");
}

/*Above is essentially printing out the information within the buffer from the recv()*/

}
}


Server:



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define PORT 4444
#define BUFFSIZE 2048
#define MAX 2048
/*Full Credit implementing command argument functions: https://stackoverflow.com/questions/52796610/multiclient-and-server-commandline-argument-issues*/
/*setup() function take the input bugger and the arguments and tokenizes the arguments into the inputBuffer*/
void setup(char inputBuffer, char *args, int *background){
const char s[4] = " tn";
char *token;
token = strtok(inputBuffer, s);
int i = 0;
while(token != NULL){
args[i] = token;
i++;
token = strtok(NULL, s);
}
args[i] = NULL;
}
/*HandleClient() function take the socket, grabs the data from the client from the buffer*/
void HandleClient(int sock){
char buffer[BUFFSIZE];
int received = -1;
char data[MAX];
memset(data, 0, MAX);
/*recv grabs info from the buffer*/
while(1){
data[0] = '';
if((received = recv(sock, buffer, BUFFSIZE, 0)) < 0){
printf("Error");
}

buffer[received] = '';

strcat(data, buffer);
if(strcmp(data, "exit") == 0){
exit(0);
}
/*Put data into an arg array and pipe*/
puts(data);
char *args[100];
setup(data, args, 0);
int pipefd[2], length;

if(pipe(pipefd)){
printf("failed to create pipe");
}
/*Fork a child*/
pid_t pid = fork();
char path[MAX];

if(pid==0)
{
close(pipefd[0]); // close the readonly side of the pipe
//close(1); // close the original stdout
dup2(pipefd[1],1); // duplicate pipfd[1] to stdout
dup2(pipefd[1], fileno(stderr));
//close(pipefd[0]); // close the readonly side of the pipe
close(pipefd[1]); // close the original write side of the pipe
printf("before execvp");
execvp(args[0],args); // finally execute the command
// exit(0);
}
else
if(pid>0)
{
close(pipefd[1]);
memset(path,'',MAX);
while(length=read(pipefd[0],path,MAX-1)){
//printf("Data read so far %sn", path);
if(send(sock,path,strlen(path),0) != strlen(path) ){
printf("Failed");
}
fflush(NULL);
//printf("Data sent so far %sn", path);
memset(path,0,MAX);
}
close(pipefd[0]);

//exit(1); removed so server will not terminate
}
else
{
printf("Error !n");
exit(0);//
}

}
}

char *decryptedMessage(char command){
int i = 0;

while (command[i] != ''){
command[i] -= 5;
i += 1;
}

return command;
}


int main(){
/*Create all the sock, server address, and pid variables*/
int sockfd, ret;
struct sockaddr_in serverAddr;

int newSocket;
struct sockaddr_in newAddr;

socklen_t addr_size;

char buffer[1024];
pid_t childpid;
/*Create a socket*/
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
printf("Error in connection.n");
exit(1);
}
printf("Server Socket is created.n");
/*Memset the serverAddr, and put the ip and port number into the serverAddr structure*/
memset(&serverAddr, '', sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

//printf("IP address is: %sn", inet_ntoa(client_addr.sin_addr));
//printf("port is: %dn", (int) ntohs(client_addr.sin_port));

/*Bind to the port*/
ret = bind(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in binding");
exit(1);
}
printf("Bind to port %dn", 4444);

if(listen(sockfd, 10) == 0){
printf("Listening....n"); //Listening to accept connections
}else{
printf("Error in binding.n");
}

while(1){
newSocket = accept(sockfd, (struct sockaddr*) &newAddr, &addr_size); //accept the socket and server address
if(newSocket < 0){
exit(1);
}
printf("Connection accepted from %s:%dn", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));

//Take the buffer from the server and send it back to the client through the socket
if((childpid = fork()) == 0){
close(sockfd);

while(1){
recv(newSocket, buffer, 1024, 0); //recv() get the buffer and set the size 1024
if(strcmp(buffer, "quit") == 0){
printf("Disconnected from %s:%dn", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));
break;
}else{
printf("Client: %sn", buffer);
send(newSocket, buffer, strlen(buffer), 0); //sending info back to the client
bzero(buffer, sizeof(buffer));
}
HandleClient(newSocket);
}
}
}


close(newSocket);
return 0;
}









share|improve this question


















  • 1





    In your client, for (int a = 0; a < historyCounter; a++){ is a problem once historyCounter exceeds 10, which it can do. You guard against this in the first loop (the storage loop), but not against it in the processing loop. You can rectify most of this by simply using historyCounter = min(historyCounter+1, 10);. That would remove the need to check against < 10 in the first loop, and fix the second implicitly. There may be other problems, but that one jumped at me so I figured i'd mention it.

    – WhozCraig
    Nov 14 '18 at 23:26











  • Thanks craig, I appreciate the help on that, that makes sense

    – DsDude
    Nov 14 '18 at 23:57
















0















I have this client and server program. I'm trying to add a history command where it displays the last 10 commands when you type "history" in the commandline, but I'm having issues with it where it won't display at all, but I'm not sure why it won't work. After I type "history" it won't display anything and I can't type any commands after which makes me have to re-launch the code be able to type unix commands in. This program works by sending unix commands such as "ls" or "date" and it will send the info from the server back to the client. It may be because my code is a little buggy, but it should still work. Any one can point me in the right direction?



Client:



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define BUFFSIZE 2048

char history[10][50];
int historyCounter = 0;

char *encryptedMessage(char command){
int i = 0;

while (command[i] != ''){
command[i] += 5;
i += 1;
}

return command;
}



int main(int argc, char *argv){
/*Created variables for socket, server address, arguement size, and a buffer*/
int clientSocket, ret, portnum;
struct sockaddr_in serverAddr;
int received = 0;
unsigned int echolen;
char buffer[BUFFSIZE];

/*If there is less than 3 arguments, print out a statement explaining to execute program
along witjh server ip and port*/
if(argc < 3){
fprintf(stderr,"usage %s <server-ip-addr> <server-port>n", argv[0]);
exit(0);
}
/*Convert port number from the commandline using atoi*/
portnum = atoi(argv[2]);

/*Create socket, and check if there is an error in the connection*/
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if(clientSocket < 0){
printf("Error in connection.n");
exit(1);
}
printf("Client Socket is created.n");
/*Memset server address*/
memset(&serverAddr, '', sizeof(serverAddr));
// memset(&buffer, '', sizeof(buffer));
// serverAddr.sin_family = AF_INET;
// serverAddr.sin_port = htons(PORT);
// serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

// bzero((char *) &serverAddr, sizeof(serverAddr));

/*Take ip address from commandline and set it into serverAddr*/
serverAddr.sin_family = AF_INET;
if(!inet_aton(argv[1], &serverAddr.sin_addr)){
fprintf(stderr, "Error invalid server IP addressn");
exit(1);
}
/*Take the port number and set it in the sin_port for connection*/
serverAddr.sin_port = htons(portnum);
/*Connect the client to the server, if less than 0, then there is an error in the connection*/
ret = connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in connection.n");
exit(1);
}
printf("Connected to server.n");
/*Initialize argument buffer*/
char s[100];
/*In the while loop we take the arguments after we connect and put them in stdin, we insert at the
end of s array*/
while(1){
int _switch = 0;
fgets(s, 100, stdin);
historyCounter++;
//s[strlen(s)-1]='';
echolen = strlen(s);
if(historyCounter < 10){
for(int i = 0; i < historyCounter; i++){
strcpy(history[i+1], history[i]);
}
}
strcpy(history[0], s);

/* send() from client, if it doesn't equal echolen then show it failed */
if(strcmp(s,"history") == 0){
_switch = 1;
int a = 0;
int b = 0;

for (int a = 0; a < historyCounter; a++){
printf("%d", historyCounter);
while(history[a][b] != ''){
printf("%c", history[a][b]);
b++;
}
b = 0;
printf("n");
}
printf("n");

}


if(_switch == 0){
if (send(clientSocket, s, echolen, 0) != echolen)
{
printf("Failed");
}

if(strcmp(s,"quit") == 0) //check if exit is typed
exit(0);
fprintf(stdout, "Message from server: ");
//fprintf(stdin, "%sn", s);
while (received < echolen)
{
ssize_t bytes = 0;
/* recv() from server, the bytes we receive are from the clientSocket */
if ((bytes = recv(clientSocket, buffer, echolen, 0)) < 1)
{
printf("Failed to get Information");
}
received += bytes;
buffer[bytes] = '';
/*WE receive the information and print in stdout what's in the buffer*/
fprintf(stdout, buffer);
}
ssize_t bytes = 0;
/*Place /0 at end of the buffer*/
do {
buffer[bytes] = '';
printf("%sn", buffer);
} while((bytes = recv(clientSocket, buffer, BUFFSIZE-1, 0))>=BUFFSIZE-1);
buffer[bytes] = '';
printf("%sn", buffer);
printf("n");
}

/*Above is essentially printing out the information within the buffer from the recv()*/

}
}


Server:



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define PORT 4444
#define BUFFSIZE 2048
#define MAX 2048
/*Full Credit implementing command argument functions: https://stackoverflow.com/questions/52796610/multiclient-and-server-commandline-argument-issues*/
/*setup() function take the input bugger and the arguments and tokenizes the arguments into the inputBuffer*/
void setup(char inputBuffer, char *args, int *background){
const char s[4] = " tn";
char *token;
token = strtok(inputBuffer, s);
int i = 0;
while(token != NULL){
args[i] = token;
i++;
token = strtok(NULL, s);
}
args[i] = NULL;
}
/*HandleClient() function take the socket, grabs the data from the client from the buffer*/
void HandleClient(int sock){
char buffer[BUFFSIZE];
int received = -1;
char data[MAX];
memset(data, 0, MAX);
/*recv grabs info from the buffer*/
while(1){
data[0] = '';
if((received = recv(sock, buffer, BUFFSIZE, 0)) < 0){
printf("Error");
}

buffer[received] = '';

strcat(data, buffer);
if(strcmp(data, "exit") == 0){
exit(0);
}
/*Put data into an arg array and pipe*/
puts(data);
char *args[100];
setup(data, args, 0);
int pipefd[2], length;

if(pipe(pipefd)){
printf("failed to create pipe");
}
/*Fork a child*/
pid_t pid = fork();
char path[MAX];

if(pid==0)
{
close(pipefd[0]); // close the readonly side of the pipe
//close(1); // close the original stdout
dup2(pipefd[1],1); // duplicate pipfd[1] to stdout
dup2(pipefd[1], fileno(stderr));
//close(pipefd[0]); // close the readonly side of the pipe
close(pipefd[1]); // close the original write side of the pipe
printf("before execvp");
execvp(args[0],args); // finally execute the command
// exit(0);
}
else
if(pid>0)
{
close(pipefd[1]);
memset(path,'',MAX);
while(length=read(pipefd[0],path,MAX-1)){
//printf("Data read so far %sn", path);
if(send(sock,path,strlen(path),0) != strlen(path) ){
printf("Failed");
}
fflush(NULL);
//printf("Data sent so far %sn", path);
memset(path,0,MAX);
}
close(pipefd[0]);

//exit(1); removed so server will not terminate
}
else
{
printf("Error !n");
exit(0);//
}

}
}

char *decryptedMessage(char command){
int i = 0;

while (command[i] != ''){
command[i] -= 5;
i += 1;
}

return command;
}


int main(){
/*Create all the sock, server address, and pid variables*/
int sockfd, ret;
struct sockaddr_in serverAddr;

int newSocket;
struct sockaddr_in newAddr;

socklen_t addr_size;

char buffer[1024];
pid_t childpid;
/*Create a socket*/
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
printf("Error in connection.n");
exit(1);
}
printf("Server Socket is created.n");
/*Memset the serverAddr, and put the ip and port number into the serverAddr structure*/
memset(&serverAddr, '', sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

//printf("IP address is: %sn", inet_ntoa(client_addr.sin_addr));
//printf("port is: %dn", (int) ntohs(client_addr.sin_port));

/*Bind to the port*/
ret = bind(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in binding");
exit(1);
}
printf("Bind to port %dn", 4444);

if(listen(sockfd, 10) == 0){
printf("Listening....n"); //Listening to accept connections
}else{
printf("Error in binding.n");
}

while(1){
newSocket = accept(sockfd, (struct sockaddr*) &newAddr, &addr_size); //accept the socket and server address
if(newSocket < 0){
exit(1);
}
printf("Connection accepted from %s:%dn", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));

//Take the buffer from the server and send it back to the client through the socket
if((childpid = fork()) == 0){
close(sockfd);

while(1){
recv(newSocket, buffer, 1024, 0); //recv() get the buffer and set the size 1024
if(strcmp(buffer, "quit") == 0){
printf("Disconnected from %s:%dn", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));
break;
}else{
printf("Client: %sn", buffer);
send(newSocket, buffer, strlen(buffer), 0); //sending info back to the client
bzero(buffer, sizeof(buffer));
}
HandleClient(newSocket);
}
}
}


close(newSocket);
return 0;
}









share|improve this question


















  • 1





    In your client, for (int a = 0; a < historyCounter; a++){ is a problem once historyCounter exceeds 10, which it can do. You guard against this in the first loop (the storage loop), but not against it in the processing loop. You can rectify most of this by simply using historyCounter = min(historyCounter+1, 10);. That would remove the need to check against < 10 in the first loop, and fix the second implicitly. There may be other problems, but that one jumped at me so I figured i'd mention it.

    – WhozCraig
    Nov 14 '18 at 23:26











  • Thanks craig, I appreciate the help on that, that makes sense

    – DsDude
    Nov 14 '18 at 23:57














0












0








0








I have this client and server program. I'm trying to add a history command where it displays the last 10 commands when you type "history" in the commandline, but I'm having issues with it where it won't display at all, but I'm not sure why it won't work. After I type "history" it won't display anything and I can't type any commands after which makes me have to re-launch the code be able to type unix commands in. This program works by sending unix commands such as "ls" or "date" and it will send the info from the server back to the client. It may be because my code is a little buggy, but it should still work. Any one can point me in the right direction?



Client:



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define BUFFSIZE 2048

char history[10][50];
int historyCounter = 0;

char *encryptedMessage(char command){
int i = 0;

while (command[i] != ''){
command[i] += 5;
i += 1;
}

return command;
}



int main(int argc, char *argv){
/*Created variables for socket, server address, arguement size, and a buffer*/
int clientSocket, ret, portnum;
struct sockaddr_in serverAddr;
int received = 0;
unsigned int echolen;
char buffer[BUFFSIZE];

/*If there is less than 3 arguments, print out a statement explaining to execute program
along witjh server ip and port*/
if(argc < 3){
fprintf(stderr,"usage %s <server-ip-addr> <server-port>n", argv[0]);
exit(0);
}
/*Convert port number from the commandline using atoi*/
portnum = atoi(argv[2]);

/*Create socket, and check if there is an error in the connection*/
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if(clientSocket < 0){
printf("Error in connection.n");
exit(1);
}
printf("Client Socket is created.n");
/*Memset server address*/
memset(&serverAddr, '', sizeof(serverAddr));
// memset(&buffer, '', sizeof(buffer));
// serverAddr.sin_family = AF_INET;
// serverAddr.sin_port = htons(PORT);
// serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

// bzero((char *) &serverAddr, sizeof(serverAddr));

/*Take ip address from commandline and set it into serverAddr*/
serverAddr.sin_family = AF_INET;
if(!inet_aton(argv[1], &serverAddr.sin_addr)){
fprintf(stderr, "Error invalid server IP addressn");
exit(1);
}
/*Take the port number and set it in the sin_port for connection*/
serverAddr.sin_port = htons(portnum);
/*Connect the client to the server, if less than 0, then there is an error in the connection*/
ret = connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in connection.n");
exit(1);
}
printf("Connected to server.n");
/*Initialize argument buffer*/
char s[100];
/*In the while loop we take the arguments after we connect and put them in stdin, we insert at the
end of s array*/
while(1){
int _switch = 0;
fgets(s, 100, stdin);
historyCounter++;
//s[strlen(s)-1]='';
echolen = strlen(s);
if(historyCounter < 10){
for(int i = 0; i < historyCounter; i++){
strcpy(history[i+1], history[i]);
}
}
strcpy(history[0], s);

/* send() from client, if it doesn't equal echolen then show it failed */
if(strcmp(s,"history") == 0){
_switch = 1;
int a = 0;
int b = 0;

for (int a = 0; a < historyCounter; a++){
printf("%d", historyCounter);
while(history[a][b] != ''){
printf("%c", history[a][b]);
b++;
}
b = 0;
printf("n");
}
printf("n");

}


if(_switch == 0){
if (send(clientSocket, s, echolen, 0) != echolen)
{
printf("Failed");
}

if(strcmp(s,"quit") == 0) //check if exit is typed
exit(0);
fprintf(stdout, "Message from server: ");
//fprintf(stdin, "%sn", s);
while (received < echolen)
{
ssize_t bytes = 0;
/* recv() from server, the bytes we receive are from the clientSocket */
if ((bytes = recv(clientSocket, buffer, echolen, 0)) < 1)
{
printf("Failed to get Information");
}
received += bytes;
buffer[bytes] = '';
/*WE receive the information and print in stdout what's in the buffer*/
fprintf(stdout, buffer);
}
ssize_t bytes = 0;
/*Place /0 at end of the buffer*/
do {
buffer[bytes] = '';
printf("%sn", buffer);
} while((bytes = recv(clientSocket, buffer, BUFFSIZE-1, 0))>=BUFFSIZE-1);
buffer[bytes] = '';
printf("%sn", buffer);
printf("n");
}

/*Above is essentially printing out the information within the buffer from the recv()*/

}
}


Server:



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define PORT 4444
#define BUFFSIZE 2048
#define MAX 2048
/*Full Credit implementing command argument functions: https://stackoverflow.com/questions/52796610/multiclient-and-server-commandline-argument-issues*/
/*setup() function take the input bugger and the arguments and tokenizes the arguments into the inputBuffer*/
void setup(char inputBuffer, char *args, int *background){
const char s[4] = " tn";
char *token;
token = strtok(inputBuffer, s);
int i = 0;
while(token != NULL){
args[i] = token;
i++;
token = strtok(NULL, s);
}
args[i] = NULL;
}
/*HandleClient() function take the socket, grabs the data from the client from the buffer*/
void HandleClient(int sock){
char buffer[BUFFSIZE];
int received = -1;
char data[MAX];
memset(data, 0, MAX);
/*recv grabs info from the buffer*/
while(1){
data[0] = '';
if((received = recv(sock, buffer, BUFFSIZE, 0)) < 0){
printf("Error");
}

buffer[received] = '';

strcat(data, buffer);
if(strcmp(data, "exit") == 0){
exit(0);
}
/*Put data into an arg array and pipe*/
puts(data);
char *args[100];
setup(data, args, 0);
int pipefd[2], length;

if(pipe(pipefd)){
printf("failed to create pipe");
}
/*Fork a child*/
pid_t pid = fork();
char path[MAX];

if(pid==0)
{
close(pipefd[0]); // close the readonly side of the pipe
//close(1); // close the original stdout
dup2(pipefd[1],1); // duplicate pipfd[1] to stdout
dup2(pipefd[1], fileno(stderr));
//close(pipefd[0]); // close the readonly side of the pipe
close(pipefd[1]); // close the original write side of the pipe
printf("before execvp");
execvp(args[0],args); // finally execute the command
// exit(0);
}
else
if(pid>0)
{
close(pipefd[1]);
memset(path,'',MAX);
while(length=read(pipefd[0],path,MAX-1)){
//printf("Data read so far %sn", path);
if(send(sock,path,strlen(path),0) != strlen(path) ){
printf("Failed");
}
fflush(NULL);
//printf("Data sent so far %sn", path);
memset(path,0,MAX);
}
close(pipefd[0]);

//exit(1); removed so server will not terminate
}
else
{
printf("Error !n");
exit(0);//
}

}
}

char *decryptedMessage(char command){
int i = 0;

while (command[i] != ''){
command[i] -= 5;
i += 1;
}

return command;
}


int main(){
/*Create all the sock, server address, and pid variables*/
int sockfd, ret;
struct sockaddr_in serverAddr;

int newSocket;
struct sockaddr_in newAddr;

socklen_t addr_size;

char buffer[1024];
pid_t childpid;
/*Create a socket*/
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
printf("Error in connection.n");
exit(1);
}
printf("Server Socket is created.n");
/*Memset the serverAddr, and put the ip and port number into the serverAddr structure*/
memset(&serverAddr, '', sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

//printf("IP address is: %sn", inet_ntoa(client_addr.sin_addr));
//printf("port is: %dn", (int) ntohs(client_addr.sin_port));

/*Bind to the port*/
ret = bind(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in binding");
exit(1);
}
printf("Bind to port %dn", 4444);

if(listen(sockfd, 10) == 0){
printf("Listening....n"); //Listening to accept connections
}else{
printf("Error in binding.n");
}

while(1){
newSocket = accept(sockfd, (struct sockaddr*) &newAddr, &addr_size); //accept the socket and server address
if(newSocket < 0){
exit(1);
}
printf("Connection accepted from %s:%dn", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));

//Take the buffer from the server and send it back to the client through the socket
if((childpid = fork()) == 0){
close(sockfd);

while(1){
recv(newSocket, buffer, 1024, 0); //recv() get the buffer and set the size 1024
if(strcmp(buffer, "quit") == 0){
printf("Disconnected from %s:%dn", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));
break;
}else{
printf("Client: %sn", buffer);
send(newSocket, buffer, strlen(buffer), 0); //sending info back to the client
bzero(buffer, sizeof(buffer));
}
HandleClient(newSocket);
}
}
}


close(newSocket);
return 0;
}









share|improve this question














I have this client and server program. I'm trying to add a history command where it displays the last 10 commands when you type "history" in the commandline, but I'm having issues with it where it won't display at all, but I'm not sure why it won't work. After I type "history" it won't display anything and I can't type any commands after which makes me have to re-launch the code be able to type unix commands in. This program works by sending unix commands such as "ls" or "date" and it will send the info from the server back to the client. It may be because my code is a little buggy, but it should still work. Any one can point me in the right direction?



Client:



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define BUFFSIZE 2048

char history[10][50];
int historyCounter = 0;

char *encryptedMessage(char command){
int i = 0;

while (command[i] != ''){
command[i] += 5;
i += 1;
}

return command;
}



int main(int argc, char *argv){
/*Created variables for socket, server address, arguement size, and a buffer*/
int clientSocket, ret, portnum;
struct sockaddr_in serverAddr;
int received = 0;
unsigned int echolen;
char buffer[BUFFSIZE];

/*If there is less than 3 arguments, print out a statement explaining to execute program
along witjh server ip and port*/
if(argc < 3){
fprintf(stderr,"usage %s <server-ip-addr> <server-port>n", argv[0]);
exit(0);
}
/*Convert port number from the commandline using atoi*/
portnum = atoi(argv[2]);

/*Create socket, and check if there is an error in the connection*/
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if(clientSocket < 0){
printf("Error in connection.n");
exit(1);
}
printf("Client Socket is created.n");
/*Memset server address*/
memset(&serverAddr, '', sizeof(serverAddr));
// memset(&buffer, '', sizeof(buffer));
// serverAddr.sin_family = AF_INET;
// serverAddr.sin_port = htons(PORT);
// serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

// bzero((char *) &serverAddr, sizeof(serverAddr));

/*Take ip address from commandline and set it into serverAddr*/
serverAddr.sin_family = AF_INET;
if(!inet_aton(argv[1], &serverAddr.sin_addr)){
fprintf(stderr, "Error invalid server IP addressn");
exit(1);
}
/*Take the port number and set it in the sin_port for connection*/
serverAddr.sin_port = htons(portnum);
/*Connect the client to the server, if less than 0, then there is an error in the connection*/
ret = connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in connection.n");
exit(1);
}
printf("Connected to server.n");
/*Initialize argument buffer*/
char s[100];
/*In the while loop we take the arguments after we connect and put them in stdin, we insert at the
end of s array*/
while(1){
int _switch = 0;
fgets(s, 100, stdin);
historyCounter++;
//s[strlen(s)-1]='';
echolen = strlen(s);
if(historyCounter < 10){
for(int i = 0; i < historyCounter; i++){
strcpy(history[i+1], history[i]);
}
}
strcpy(history[0], s);

/* send() from client, if it doesn't equal echolen then show it failed */
if(strcmp(s,"history") == 0){
_switch = 1;
int a = 0;
int b = 0;

for (int a = 0; a < historyCounter; a++){
printf("%d", historyCounter);
while(history[a][b] != ''){
printf("%c", history[a][b]);
b++;
}
b = 0;
printf("n");
}
printf("n");

}


if(_switch == 0){
if (send(clientSocket, s, echolen, 0) != echolen)
{
printf("Failed");
}

if(strcmp(s,"quit") == 0) //check if exit is typed
exit(0);
fprintf(stdout, "Message from server: ");
//fprintf(stdin, "%sn", s);
while (received < echolen)
{
ssize_t bytes = 0;
/* recv() from server, the bytes we receive are from the clientSocket */
if ((bytes = recv(clientSocket, buffer, echolen, 0)) < 1)
{
printf("Failed to get Information");
}
received += bytes;
buffer[bytes] = '';
/*WE receive the information and print in stdout what's in the buffer*/
fprintf(stdout, buffer);
}
ssize_t bytes = 0;
/*Place /0 at end of the buffer*/
do {
buffer[bytes] = '';
printf("%sn", buffer);
} while((bytes = recv(clientSocket, buffer, BUFFSIZE-1, 0))>=BUFFSIZE-1);
buffer[bytes] = '';
printf("%sn", buffer);
printf("n");
}

/*Above is essentially printing out the information within the buffer from the recv()*/

}
}


Server:



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define PORT 4444
#define BUFFSIZE 2048
#define MAX 2048
/*Full Credit implementing command argument functions: https://stackoverflow.com/questions/52796610/multiclient-and-server-commandline-argument-issues*/
/*setup() function take the input bugger and the arguments and tokenizes the arguments into the inputBuffer*/
void setup(char inputBuffer, char *args, int *background){
const char s[4] = " tn";
char *token;
token = strtok(inputBuffer, s);
int i = 0;
while(token != NULL){
args[i] = token;
i++;
token = strtok(NULL, s);
}
args[i] = NULL;
}
/*HandleClient() function take the socket, grabs the data from the client from the buffer*/
void HandleClient(int sock){
char buffer[BUFFSIZE];
int received = -1;
char data[MAX];
memset(data, 0, MAX);
/*recv grabs info from the buffer*/
while(1){
data[0] = '';
if((received = recv(sock, buffer, BUFFSIZE, 0)) < 0){
printf("Error");
}

buffer[received] = '';

strcat(data, buffer);
if(strcmp(data, "exit") == 0){
exit(0);
}
/*Put data into an arg array and pipe*/
puts(data);
char *args[100];
setup(data, args, 0);
int pipefd[2], length;

if(pipe(pipefd)){
printf("failed to create pipe");
}
/*Fork a child*/
pid_t pid = fork();
char path[MAX];

if(pid==0)
{
close(pipefd[0]); // close the readonly side of the pipe
//close(1); // close the original stdout
dup2(pipefd[1],1); // duplicate pipfd[1] to stdout
dup2(pipefd[1], fileno(stderr));
//close(pipefd[0]); // close the readonly side of the pipe
close(pipefd[1]); // close the original write side of the pipe
printf("before execvp");
execvp(args[0],args); // finally execute the command
// exit(0);
}
else
if(pid>0)
{
close(pipefd[1]);
memset(path,'',MAX);
while(length=read(pipefd[0],path,MAX-1)){
//printf("Data read so far %sn", path);
if(send(sock,path,strlen(path),0) != strlen(path) ){
printf("Failed");
}
fflush(NULL);
//printf("Data sent so far %sn", path);
memset(path,0,MAX);
}
close(pipefd[0]);

//exit(1); removed so server will not terminate
}
else
{
printf("Error !n");
exit(0);//
}

}
}

char *decryptedMessage(char command){
int i = 0;

while (command[i] != ''){
command[i] -= 5;
i += 1;
}

return command;
}


int main(){
/*Create all the sock, server address, and pid variables*/
int sockfd, ret;
struct sockaddr_in serverAddr;

int newSocket;
struct sockaddr_in newAddr;

socklen_t addr_size;

char buffer[1024];
pid_t childpid;
/*Create a socket*/
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
printf("Error in connection.n");
exit(1);
}
printf("Server Socket is created.n");
/*Memset the serverAddr, and put the ip and port number into the serverAddr structure*/
memset(&serverAddr, '', sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

//printf("IP address is: %sn", inet_ntoa(client_addr.sin_addr));
//printf("port is: %dn", (int) ntohs(client_addr.sin_port));

/*Bind to the port*/
ret = bind(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in binding");
exit(1);
}
printf("Bind to port %dn", 4444);

if(listen(sockfd, 10) == 0){
printf("Listening....n"); //Listening to accept connections
}else{
printf("Error in binding.n");
}

while(1){
newSocket = accept(sockfd, (struct sockaddr*) &newAddr, &addr_size); //accept the socket and server address
if(newSocket < 0){
exit(1);
}
printf("Connection accepted from %s:%dn", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));

//Take the buffer from the server and send it back to the client through the socket
if((childpid = fork()) == 0){
close(sockfd);

while(1){
recv(newSocket, buffer, 1024, 0); //recv() get the buffer and set the size 1024
if(strcmp(buffer, "quit") == 0){
printf("Disconnected from %s:%dn", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));
break;
}else{
printf("Client: %sn", buffer);
send(newSocket, buffer, strlen(buffer), 0); //sending info back to the client
bzero(buffer, sizeof(buffer));
}
HandleClient(newSocket);
}
}
}


close(newSocket);
return 0;
}






c server client






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 14 '18 at 23:15









DsDudeDsDude

557




557








  • 1





    In your client, for (int a = 0; a < historyCounter; a++){ is a problem once historyCounter exceeds 10, which it can do. You guard against this in the first loop (the storage loop), but not against it in the processing loop. You can rectify most of this by simply using historyCounter = min(historyCounter+1, 10);. That would remove the need to check against < 10 in the first loop, and fix the second implicitly. There may be other problems, but that one jumped at me so I figured i'd mention it.

    – WhozCraig
    Nov 14 '18 at 23:26











  • Thanks craig, I appreciate the help on that, that makes sense

    – DsDude
    Nov 14 '18 at 23:57














  • 1





    In your client, for (int a = 0; a < historyCounter; a++){ is a problem once historyCounter exceeds 10, which it can do. You guard against this in the first loop (the storage loop), but not against it in the processing loop. You can rectify most of this by simply using historyCounter = min(historyCounter+1, 10);. That would remove the need to check against < 10 in the first loop, and fix the second implicitly. There may be other problems, but that one jumped at me so I figured i'd mention it.

    – WhozCraig
    Nov 14 '18 at 23:26











  • Thanks craig, I appreciate the help on that, that makes sense

    – DsDude
    Nov 14 '18 at 23:57








1




1





In your client, for (int a = 0; a < historyCounter; a++){ is a problem once historyCounter exceeds 10, which it can do. You guard against this in the first loop (the storage loop), but not against it in the processing loop. You can rectify most of this by simply using historyCounter = min(historyCounter+1, 10);. That would remove the need to check against < 10 in the first loop, and fix the second implicitly. There may be other problems, but that one jumped at me so I figured i'd mention it.

– WhozCraig
Nov 14 '18 at 23:26





In your client, for (int a = 0; a < historyCounter; a++){ is a problem once historyCounter exceeds 10, which it can do. You guard against this in the first loop (the storage loop), but not against it in the processing loop. You can rectify most of this by simply using historyCounter = min(historyCounter+1, 10);. That would remove the need to check against < 10 in the first loop, and fix the second implicitly. There may be other problems, but that one jumped at me so I figured i'd mention it.

– WhozCraig
Nov 14 '18 at 23:26













Thanks craig, I appreciate the help on that, that makes sense

– DsDude
Nov 14 '18 at 23:57





Thanks craig, I appreciate the help on that, that makes sense

– DsDude
Nov 14 '18 at 23:57












1 Answer
1






active

oldest

votes


















0














fgets() reads until newline but also copies that newline at the end of input buffer. In strcmp() for history command it can fail. Pls check man page of fgets().






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53310177%2fadding-history-command-to-multiclient-server-program%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    fgets() reads until newline but also copies that newline at the end of input buffer. In strcmp() for history command it can fail. Pls check man page of fgets().






    share|improve this answer




























      0














      fgets() reads until newline but also copies that newline at the end of input buffer. In strcmp() for history command it can fail. Pls check man page of fgets().






      share|improve this answer


























        0












        0








        0







        fgets() reads until newline but also copies that newline at the end of input buffer. In strcmp() for history command it can fail. Pls check man page of fgets().






        share|improve this answer













        fgets() reads until newline but also copies that newline at the end of input buffer. In strcmp() for history command it can fail. Pls check man page of fgets().







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 15 '18 at 2:55









        anandanand

        1377




        1377
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53310177%2fadding-history-command-to-multiclient-server-program%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Xamarin.iOS Cant Deploy on Iphone

            Glorious Revolution

            Dulmage-Mendelsohn matrix decomposition in Python