多客户端和服务器命令行参数问题

时间:2018-10-13 19:37:19

标签: c server client

我有一个可以处理多个客户端的服务器代码。客户端程序可以连接到服务器并发出Unix命令,例如ls,date,clear等。我有两个我无法弄清的问题。 1)当我最初输入ls作为参数时,它将返回一些奇怪的垃圾,然后如果我再次输入ls,它将开始正常工作。因此,仅在一开始,它就会给我带来垃圾。 2)当我在终端上输入参数'ps -ael'时,它将正常工作,但是之后我收到一条'Failed'消息,该消息来自客户端代码,特别是在while(1)循环中if (send(clientSocket, s, echolen, 0) != echolen),这是发生错误的地方。我很想知道是否有人可以指出问题所在,我认为这可能是因为我创建的char数组太大了,但我不确定。

客户:

#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

int main(int argc, char *argv[]){

int clientSocket, ret, portnum;
struct sockaddr_in serverAddr;
int received = 0;
unsigned int echolen;
char buffer[1024];

if(argc < 3){
    fprintf(stderr,"usage %s <server-ip-addr> <server-port>\n", argv[0]);
    exit(0);
}

portnum = atoi(argv[2]);


clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if(clientSocket < 0){
    printf("Error in connection.\n");
    exit(1);
}
printf("Client Socket is created.\n");

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));
serverAddr.sin_family = AF_INET;
if(!inet_aton(argv[1], &serverAddr.sin_addr)){
    fprintf(stderr, "Error invalid server IP address\n");
    exit(1);
}

serverAddr.sin_port = htons(portnum);

ret = connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
    printf("Error in connection.\n");
    exit(1);
}
printf("Connected to server.\n");

char s[100];

while(1){
    fgets(s, 100, stdin);
    s[strlen(s)-1]='\0';
    echolen = strlen(s);
    /*  send() from client; */
    if (send(clientSocket, s, echolen, 0) != echolen) 
    {
        printf("Failed");
    }
    if(strcmp(s,"exit") == 0) // check if exit is typed
    exit(0);
    fprintf(stdout, "Message from server: ");
    while (received < echolen) 
    {
        int bytes = 0;
        /* recv() from server; */
        if ((bytes = recv(clientSocket, buffer, echolen, 0)) < 1) 
        {
            printf("Failed to get Information");
        }
        received += bytes;
        buffer[bytes] = '\0';

        fprintf(stdout, buffer);
    }
    int bytes = 0;

    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");

}
}

服务器:

#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

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;
}

void HandleClient(int sock){
char buffer[BUFFSIZE];
int received = -1;
char data[MAX];
memset(data, 0, MAX);

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);
    }

    puts(data);
    char *args[100];
    setup(data, args, 0);
    int pipefd[2], length;

    if(pipe(pipefd)){
        printf("failed to create pipe");
    }

    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);//
        }

}
}

int main(){

int sockfd, ret;
struct sockaddr_in serverAddr;

int newSocket;
struct sockaddr_in newAddr;

socklen_t addr_size;

char buffer[1024];
pid_t childpid;

sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
    printf("Error in connection.\n");
    exit(1);
}
printf("Server Socket is created.\n");

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");

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");
}else{
    printf("Error in binding.\n");
}

while(1){
    newSocket = accept(sockfd, (struct sockaddr*) &newAddr, &addr_size);
    if(newSocket < 0){
        exit(1);
    }
    printf("Connection accepted from %s:%d\n", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));

    //worker
    if((childpid = fork()) == 0){
        close(sockfd);

        while(1){
            recv(newSocket, buffer, 1024, 0);
            if(strcmp(buffer, ":exit") == 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);
                bzero(buffer, sizeof(buffer));
            }
            HandleClient(newSocket);
        }
    }
}


close(newSocket);
return 0;
}

0 个答案:

没有答案