2

これは、教育目的の基本的な TCP サーバーの実装です。エラーや改善点はありますか。どんな提案でも大歓迎です!

疑問があるだけです:

signal(SIGCHLD, SIG_IGN);

その呼び出しは、zoombie-child プロセスを防ぐために使用されますか?

 #include <netinet/in.h>
 #include <sys/socket.h>
 #include <netdb.h>

 #include <sys/signal.h>

 #include <unistd.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>

 #define BACKLOG 5
 #define MAXSIZE 1024 //max-bytes for read-buffer

void main(){

int sock_ds, ret, length;
int acc_ds; //Accept socket descriptor

struct sockaddr_in addr; //this addres
struct sockaddr rem_addr; //remote address (generic)

char buff[MAXSIZE];

sock_ds = socket(AF_INET, SOCK_STREAM, 0); // => TCP

bzero((char *)&addr, sizeof(addr)); //reset struct
addr.sin_family = AF_INET;
addr.sin_port = htons(25000);
addr.sin_addr.s_addr = INADDR_ANY;
ret = bind(sock_ds, &addr, sizeof(addr));
if(ret == -1){
    perror("Binding error");
    exit(1);
}

ret = listen(sock_ds, BACKLOG); // backlog queue
    if(ret == -1){
    perror("Listen error");
    exit(1);
}

length = sizeof(rem_addr);
signal(SIGCHLD, SIG_IGN); //zombie children management

/*Busy-waiting (server) and concurrency */
while(1){

    /*Repeat until success*/
    while(acc_ds = accept(sock_ds, &rem_addr, &length) == -1){

        if(fork() == 0){ //child-process

            close(sock_ds); //unused from child
            do{
                read(acc_ds, buff, MAXSIZE);
                printf("Message from remote host:&s\n", buff);

            }while(strcmp(buff, "quit") == 0);
            /*Transimission completed: server response  */
            write(acc_ds, "Reading Done", 10);
            close(acc_ds); //socket closed
            exit(0); //exiting from child
        }
        else{
            close(acc_ds); //unused from parent
        }
    }
}

}

4

3 に答える 3

3
  1. の戻り値の型は でmainはありませんint。そのはず。戻るEXIT_SUCCESSか、EXIT_FAILURE.
  2. 呼び出しの結果はsocket()チェックされません。bind失敗するはずですがperror()、実際のエラーの代わりに「無効な引数」が表示されます。
  3. の戻り値がread()チェックされないため、印刷時に未定義の動作が発生する可能性があります。
  4. &s指定されたフォーマットはありません%s
  5. %snull で終わる文字列が必要です。これはコードによって保証されていません (ポイント 3 を参照)。strcmp()がらくたになるかもしれません。

についてはSIGCHLD、@cnicutar が親切に答えてくれました。追加するものは何もありません。

それが役に立てば幸い。幸運を!

于 2013-02-16T23:01:00.533 に答える
2

はい、まさにそれが SIGCHLD を無視する目的です。TLPI より:

停止した子プロセスを処理する可能性はさらにあります。SIGCHLD の性質を明示的に SIG_IGN に設定すると、その後終了する子プロセスは、ゾンビに変換されるのではなく、システムからすぐに削除されます。

これは、Unix 実装全体で標準です。

于 2013-02-16T22:52:27.047 に答える