2016-03-14 64 views
0

我已經編寫了一個基於套接字的多客戶端服務器和一個客戶端作爲assigment,但我似乎無法擺脫分叉進程。每當我關閉客戶端,或輸入退出命令時,該過程似乎都不會結束。當檢查ps aux| grep server有一個過程。我怎樣才能擺脫他們,關閉叉派官員時我做錯了什麼。在套接字服務器中殺死分叉進程

服務器:

#include <stdio.h> 
#include <stdlib.h> 
#include <strings.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <time.h> 

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

void doprocessing (int sock) 
{ 
    int n; 
    char buffer[5]; 
    time_t rawtime; 
    char tim[22]; 
    char dat[20]; 
    char day[16]; 
    char yer[18]; 

    while(1) 
    { 
    bzero(buffer,5); 
    n = read(sock,buffer,5); 

    if (n < 0) error("ERROR reading from socket"); 

    printf("Got %.3s command.\n",buffer); 

    if (strcasecmp(buffer, "tim\n") == 0) 
    { 
     rawtime = time(NULL); 
     strncpy(tim, "Current time: ", 14); 
     strncpy(tim+14, (ctime(&rawtime))+11, 8); 
     n = write(sock, tim, 22); 
    } 
    else if (strcasecmp(buffer, "dat\n") == 0) 
    { 
     rawtime = time(NULL); 
     strncpy(dat, "Current date: ", 14); 
     strncpy(dat+14, (ctime(&rawtime))+4, 6); 
     n = write(sock, dat, 20); 
    } 
    else if (strcasecmp(buffer, "day\n") == 0) 
    { 
     rawtime = time(NULL); 
     strncpy(day, "Current day: ", 13); 
     strncpy(day+13, (ctime(&rawtime)), 3); 
     n = write(sock, day, 16); 
    } 
    else if (strcasecmp(buffer, "yer\n") == 0) 
    { 
     rawtime = time(NULL); 
     strncpy(yer, "Current year: ", 14); 
     strncpy(yer+14, (ctime(&rawtime))+20, 4); 
     n = write(sock, yer, 18); 
    } 
    else if (strcasecmp(buffer, "com\n") == 0) 
    { 
     n = write(sock, "TIM - current time\nDAT - Month and day\nDAY - current weekday\nYER - Year\nEXT - exit", 82); 
    } 
    else if (strcasecmp(buffer, "ext\n") == 0) 
    { 
     n = write(sock, "Exiting", 7); 
     break; 
    } 
    else n = write(sock, "Wrong command enter COM to see commands.",40); 

    if (n < 0) error("ERROR writing to socket");} 
    } 

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

    if (argc < 2) 
    { 
     fprintf(stderr, "ERROR, no port provided"); 
     exit(1); 
    } 

    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_port = htons(portno); 
    serv_addr.sin_addr.s_addr = INADDR_ANY; 

    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) error("ERROR on binding"); 

    listen(sockfd, 5); 
    clilen = sizeof(cli_addr); 

    while(1) 
    { 
     newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); 
     if (newsockfd < 0) error("ERROR on accept"); 


     pid = fork(); 

     if (pid < 0) error("ERROR on fork"); 

     if (pid == 0) 
     { 
      close(sockfd); 
      doprocessing(newsockfd); 
      exit(-1); 
     } 
     else close(newsockfd); 
    } 
    close(sockfd); 
    return 0; 
} 

客戶:

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

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

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

    char rbuffer[256]; 
    char sbuffer[256]; 

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

    portno = atoi(argv[2]); 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 

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

    server = gethostbyname(argv[1]); 

    if (server == NULL) 
    { 
     fprintf(stderr,"ERROR, no such host\n"); 
     exit(0); 
    } 

    bzero((char *) &serv_addr, sizeof(serv_addr)); 
    serv_addr.sin_family = AF_INET; 
    bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length); 
    serv_addr.sin_port = htons(portno); 

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

    while(1) 
    { 
     printf("Enter a command: "); 
     bzero(sbuffer,sizeof(sbuffer)); 
     fgets(sbuffer,255,stdin); 
     n = write(sockfd,sbuffer,5); 
     if (n < 0) error("ERROR writing to socket"); 

     bzero(rbuffer,sizeof(rbuffer)); 
     n = read(sockfd,rbuffer,255); 
     if (n < 0) error("ERROR reading from socket"); 

     printf("%s\n",rbuffer); 

     if (strcasecmp(sbuffer, "ext\n") == 0) break; 
    } 
    close(sockfd); 
    return 0; 
} 

回答

2

一種方法將是在PS輸出中可見爲 '已不存在'(有時也稱爲殭屍過程),直到它的退出狀態將通過wait()waitpid()收集。

有擺脫這些殭屍程序的以下幾個方面:

  1. 等待父進程使用wait()waitpid()孩子完成。顯然,這樣做很難在父母身上做任何事情。
  2. 在此線程內部產生子代並waitpid後立即創建單獨的線程。
  3. 在您的父母中,在此處理程序內安裝SIGCHLD信號處理程序和waitpid()
  4. 如果你的系統允許,設置忽略SIGCHLD信號。