Adding history command to multiclient server program
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
add a comment |
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
1
In your client,for (int a = 0; a < historyCounter; a++){
is a problem oncehistoryCounter
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 usinghistoryCounter = 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
add a comment |
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
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
c server client
asked Nov 14 '18 at 23:15
DsDudeDsDude
557
557
1
In your client,for (int a = 0; a < historyCounter; a++){
is a problem oncehistoryCounter
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 usinghistoryCounter = 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
add a comment |
1
In your client,for (int a = 0; a < historyCounter; a++){
is a problem oncehistoryCounter
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 usinghistoryCounter = 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
add a comment |
1 Answer
1
active
oldest
votes
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().
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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().
add a comment |
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().
add a comment |
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().
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().
answered Nov 15 '18 at 2:55
anandanand
1377
1377
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
1
In your client,
for (int a = 0; a < historyCounter; a++){
is a problem oncehistoryCounter
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 usinghistoryCounter = 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