У меня есть эта клиентская и серверная программа.Я пытаюсь добавить команду истории, где она отображает последние 10 команд при вводе «истории» в командной строке, но у меня возникают проблемы с ней, когда она вообще не отображается, но я не знаю, почемуэто не сработает.После того, как я наберу «history», он ничего не отобразит, и я не могу вводить какие-либо команды, после чего мне приходится перезапускать код, чтобы иметь возможность вводить команды Unix. Эта программа работает, отправляя команды Unix, такие как «ls»."или" date "и он отправит информацию с сервера обратно клиенту.Это может быть потому, что мой код немного глючит, но он все равно должен работать.Кто-нибудь может указать мне правильное направление?
Клиент:
#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] != '\0'){
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, '\0', sizeof(serverAddr));
// memset(&buffer, '\0', 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 address\n");
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 \0 at the
end of s array*/
while(1){
int _switch = 0;
fgets(s, 100, stdin);
historyCounter++;
//s[strlen(s)-1]='\0';
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] != '\0'){
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, "%s\n", 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] = '\0';
/*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] = '\0';
printf("%s\n", buffer);
} while((bytes = recv(clientSocket, buffer, BUFFSIZE-1, 0))>=BUFFSIZE-1);
buffer[bytes] = '\0';
printf("%s\n", buffer);
printf("\n");
}
/*Above is essentially printing out the information within the buffer from the recv()*/
}
}
Сервер:
#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] = " \t\n";
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] = '\0';
if((received = recv(sock, buffer, BUFFSIZE, 0)) < 0){
printf("Error");
}
buffer[received] = '\0';
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,'\0',MAX);
while(length=read(pipefd[0],path,MAX-1)){
//printf("Data read so far %s\n", path);
if(send(sock,path,strlen(path),0) != strlen(path) ){
printf("Failed");
}
fflush(NULL);
//printf("Data sent so far %s\n", 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] != '\0'){
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, '\0', 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: %s\n", inet_ntoa(client_addr.sin_addr));
//printf("port is: %d\n", (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 %d\n", 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:%d\n", 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:%d\n", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));
break;
}else{
printf("Client: %s\n", buffer);
send(newSocket, buffer, strlen(buffer), 0); //sending info back to the client
bzero(buffer, sizeof(buffer));
}
HandleClient(newSocket);
}
}
}
close(newSocket);
return 0;
}