1

基本的に大きなmain()関数で構成されるCコードが渡されました。私は現在、コードの意図を明確にするために、メソッドをより小さな関数に展開しようとしています。しかし、私はいくつかの問題を抱えています:

void main(int argc, char *argv[])
{
    if(argc != 3)
    {
        printf("Usage: table-server <port> <n_lists>\n");
        return;
    }
    int port = atoi(argv[1]), n_lists = atoi(argv[2]);
    if(port < 1024 || port > 49151 || n_lists < 1)
    {
        printf("Invalid args.\n");
        return;
    }
    signal(SIGPIPE, SIG_IGN);
    int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    struct sockaddr_in s_addr;
    s_addr.sin_family = AF_INET;
    s_addr.sin_port = htons(port);
    s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    if(bind(sockfd, (struct sockaddr *)&s_addr, sizeof(s_addr)) < 0)
    {
        printf("(bind).\n");
        return;
    }
    if(listen(sockfd, SOMAXCONN) < 0)
    {
        printf("(listen).\n");
        return;
    }

このコードの関数で4つの主な懸念事項を特定できます。

  1. 引数の数が正しいことを確認します。
  2. コマンドライン引数からポートを取得します。
  3. 呼び出し信号(SIGPIPE、SIG_IGN)。
  4. 実際にソケットとの接続を試みてください。

これを小さな関数にリファクタリングしようとするときの問題は、主にエラー処理に関連しています。たとえば、1のロジックを抽出しようとすると、次のようになります。

int verify_number_of_args(int argc) {
    if (argc != 3) {
        printf("...");
        return -1;
    }
    return 0;
}

それを呼び出すと、このようなものになります

if (verify_number_of_args(argc) == -1) return;

これは実際にはそれほど悪くはありません。さて、ソケットの場合、それは両方sockfds_addrも返される必要があるので、はるかに面倒であり、さらにステータスの戻り値があります。

int sockfd;
struct sockaddr_in* s_addr;
if (create_socket(port, &sockfd, s_addr) == -1)
    return;

これは、私のメインの方法をできるだけ単純で明確にしようとする目的を打ち破ります。もちろん、.cファイル内のグローバル変数に頼ることはできますが、それはあまり良い考えではないようです。

この種のことをCで一般的にどのように処理しますか?

4

3 に答える 3