客户端和服务器,executiolg命令之间的通信

问题描述 投票:0回答:2

我试图做一个命令行,基于Socket communication.My唯一的问题是,经过exexvp执行(和被印在客户端的数据),客户端接近,我希望让他活着。

这是我的代码:

client.c

#include <unistd.h> 
#include <stdio.h> 
#include <sys/socket.h> 
#include <stdlib.h> 
#include <netinet/in.h> 
#include <string.h> 
#include <sys/types.h>
#include <netdb.h>
#define PORT_NUMBER 1754
#define HOST_NUMBER

void error(const char *msg) 
{ 
    perror(msg); 
    exit(0); 
}

int main(int argc, char *argv[]) 
{ 
    int sockfd, port_number, n;     
    struct sockaddr_in serv_addr; 
    struct hostent *server;

    char buffer[256];

    if (argc < 3) { 
        //fprintf(stderr, "usage %s hostname port\n", argv[0]); 
        //first parameter is ip address
        printf("usage %s hostname port\n", argv[0]);        
        exit(0); 
    } 
    port_number = atoi(argv[2]);                        

    sockfd = socket(AF_INET, SOCK_STREAM, 0); 

    if (sockfd < 0 ) 
        error("ERROR opening socket!Socket failed!"); 

    printf("Trying to connect...\n");
    server = gethostbyname(argv[1]);  //ip address

    if (server == NULL) { 
        error( "ERROR, no such host"); 
        //fprintf(stderr, "ERROR, no such host\n");  exit(0); 
    } 
    bzero((char *) &serv_addr, sizeof(serv_addr));

    serv_addr.sin_family = AF_INET;  //AF_UNIX

    bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);

    serv_addr.sin_port = htons(port_number); 

    if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 
        error("ERROR connecting"); 

    printf("Connected!\n");
    printf("%s_>\n",argv[1]);

    while(1) {
        printf("Please enter the message: "); //THE CLIENT MUST WRITE A COMMAND

        fgets(buffer, 256, stdin);     //apo stdin sto buffer
        n = write(sockfd, buffer, strlen(buffer)); //apo buffer sto socket

        if(n < 0 ) {
            error("ERROR writing to socket");
        }
        bzero(buffer, 256);

        if ( recv(sockfd, buffer, 256, 0) < 0) {
            printf("Server closed connection\n");
        }
        printf("%s\n", buffer);
    }
    return 0;
}

sever.c

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

void parse(char *vector_args[20], char *buffer){
    buffer[strcspn(buffer, "\n")] =0;

    int i=0;
    char * pch;

    pch = strtok (buffer," "); 

    while (pch != NULL )
    {
        vector_args[i]=pch;                
        printf (" %s\n",pch);
        pch = strtok (NULL, " ");          
        i++;
    }

    vector_args[i]=NULL;                             
    int k=0;
    for(k=0; k<=i; k++) {
        printf("vector %d = %s \n",k,vector_args[k]);
    }
}

int main(int argc, char *argv[])
{
    int sockfd, newsockfd, portno;
    socklen_t clilen;
    char buffer[256];
    struct sockaddr_in serv_addr, cli_addr;
    int n;
    char str[INET_ADDRSTRLEN];

    char *vector_args[20];

    int status;
    char *fd[2];
    if (argc < 2)
    {
        fprintf(stderr, "No port provided\n");
        exit(1);
    }
    unlink("sockfd");    //remove any old socket
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
        error("ERROR opening socket");
    bzero((char *) &serv_addr, sizeof(serv_addr));
    portno = atoi(argv[1]);
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(portno);
    if (bind(sockfd,(struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
        error("ERROR on binding");
    int l = listen(sockfd, 5);
    if (l < 0) 
    { 
            error("listen failed!"); 

    }
    clilen = sizeof(cli_addr);
    printf( "Server waiting for a connection...\n " );
    while(1) {
        newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
        if (newsockfd < 0)
            error("ERROR on accept");

        if (inet_ntop(AF_INET, &cli_addr.sin_addr, str, INET_ADDRSTRLEN) == NULL) {
            fprintf(stderr, "Could not convert byte to address\n");
            exit(1);
        }

        fprintf(stdout, "Connected!\nThe client address is :%s\n", str);

        //fork new process
        int pid = fork();

        if (pid == -1 ) {
            error("ERROR in new process creation");
            close(newsockfd);
            continue;
        }else if( pid != 0){
            //parent process
            close(newsockfd);//h edw h prin to continue
            printf( " I am parent process %d\n " ,getpid());     //BGALE
            if (wait(&status)== -1) /* Wait for child*/
            {
                perror( " wait " );
            }
            check_child_exit(status);
            continue;
         }else if (pid == 0) {
              //child process
            close(sockfd);

            bzero(buffer, 256);
            while(1) {
                n = read(newsockfd, buffer, 255); //apo socket ston buffer 
                if (n < 0 )
                    error("ERROR reading from socket");

                printf("Here is the message: %s\n", buffer);
                n = write(newsockfd, "I got your message", 18);
                bzero(buffer, 256);
                close(1);                //close stdin
                dup2( newsockfd, 1); 
                close(0);                //close stdout
                dup2( newsockfd, 0);     

                parse(vector_args,buffer);

                execvp(vector_args[0] , vector_args );          

                perror( " execvp " );
                exit(EXIT_FAILURE);

                bzero(buffer, 256);
            }
            close(newsockfd);
            break;
       }   
    }
}

你有我怎么会改变我的代码,以正常工作任何想法?

c fork exec
2个回答
0
投票

环路

    while (1) {
        ....
        execvp(....);
    }

有效地执行一次。其原因是,成功的execvp替换任何vector_args请求的代码,并在完成后的执行过程刚刚退出。

如果我理解正确的话你的目标(每个连接一个过程,执行循环外部命令),你还需要一个岔路口,沿行

    while (1) {
        ....
        if ((pid = fork()) == 0) {
            execvp(....);
        } else if (pid > 0) {
            waitpid(....);
        } else {
            handle_error();
        }
    }

0
投票

如果客户端发送pwd,服务器可能的recv p w dpw dpwd等。

在我看来,如果客户要发送pwd,客户端应该发送pwd\n,服务器将读取命令,直到\n。如果服务器要发送123,服务器应该发送123\0,客户端将读到\0。我写的一个很小的例子,你可以从中吸取教训。服务器代码将继续下去,直到客户端退出。

server.c

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

void parse(char** argv, char* buffer) {
  int i = 0;
  argv[i] = strtok(buffer, " ");

  while (argv[i] != NULL) argv[++i] = strtok(NULL, " ");
}

void handle_client(int con_socket) {
  for (;;) {
    char buf[1024];
    ssize_t i = 0;
    for (;;) {
      ssize_t ret = read(con_socket, buf + i, 1);
      if (ret == 0) return;
      if (buf[i] == '\n') {
        buf[i] = '\0';
        break;
      }
      ++i;
    }

    int pipe_fd[2];
    pipe(pipe_fd);

    if (fork() == 0) {
      close(con_socket);
      dup2(pipe_fd[1], 1);
      close(pipe_fd[0]);
      close(pipe_fd[1]);

      char* argv[25];
      parse(argv, buf);

      execvp(argv[0], argv);
      exit(EXIT_FAILURE);
    } else {
      close(pipe_fd[1]);
      for (;;) {
        ssize_t ret = read(pipe_fd[0], buf, sizeof(buf));
        if (ret == 0) {
          write(con_socket, "", 1);
          break;
        }
        write(con_socket, buf, ret);
      }
      wait(NULL);
    }
  }
}

int main() {
  const char* server_ip = "127.0.0.1";
  uint16_t server_port = 6666;

  struct sockaddr_in server_addr;
  bzero(&server_addr, sizeof server_addr);
  server_addr.sin_family = AF_INET;
  server_addr.sin_port = htons(server_port);
  inet_pton(AF_INET, server_ip, &server_addr.sin_addr);

  int listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  int opt = 1;
  setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
  bind(listen_socket, (struct sockaddr*)(&server_addr),
       (socklen_t)(sizeof server_addr));
  listen(listen_socket, 5);

  for (;;) {
    int con_socket = accept(listen_socket, NULL, NULL);
    if (fork() > 0) {
      close(con_socket);
      wait(NULL);
      continue;
    } else {
      close(listen_socket);
      handle_client(con_socket);
      close(con_socket);
      break;
    }
  }
  return 0;
}

client.c

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

int main() {
  const char* server_ip = "127.0.0.1";
  uint16_t server_port = 6666;

  struct sockaddr_in server_addr;
  bzero(&server_addr, sizeof server_addr);
  server_addr.sin_family = AF_INET;
  server_addr.sin_port = htons(server_port);
  inet_pton(AF_INET, server_ip, &server_addr.sin_addr);

  int sockfd = socket(AF_INET, SOCK_STREAM, 0);

  connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));

  for (;;) {
    printf(">> ");
    char buffer[256];
    fgets(buffer, 256, stdin);
    if (strlen(buffer) == 0) continue;
    write(sockfd, buffer, strlen(buffer));

    for (;;) {
      ssize_t ret = recv(sockfd, buffer, 256, 0);
      buffer[ret] = '\0';
      printf("%s", buffer);
      if (buffer[ret - 1] == '\0') break;
    }
  }
  return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.