質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.36%

  • C

    2523questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • FTP

    235questions

    FTP(File Transfer Protocol)は、ネットワークでのファイル転送を行うための通信プロトコルの1つである。

C言語でFTP接続のプログラム。

受付中

回答 0

投稿 2017/11/26 11:14

  • 評価
  • クリップ 1
  • VIEW 122

shunichi1104

score 0

前提・実現したいこと

XcodeでC言語を使ってFTP接続をやりたいのですが以下の23という数字が出て止まってしいます。
原因は何でしょうか?
よろしくお願いします。

発生している問題・エラーメッセージ

220 FTP Server ready.
--> USER ユーザーネーム
331 Password required for ユーザーネーム
--> PASS パスワード
230 User ユーザーネーム logged in.
--> PORT ipアドレスp1.ipアドレスp2.ipアドレスp3.ipアドレスp4.ポート1.ポート2
23 ←これしか出ない

該当のソースコード

/* $Id: ftp-client.c,v 1.4 2004/05/29 05:36:31 68user Exp $ */

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

#define BUF_LEN 256             /* バッファのサイズ */

int debug_flg = 1;      /* -d オプションを付けると turn on する */


/*--------------------------------------------------
 * ソケットから1行読み込む
 */
char *read_line(int socket, char *p){
    char *org_p = p;

    while (1){
        if ( read(socket, p, 1) == 0 ) break;
        if ( *p == '\n' ) break;
        p++;
    }
    *(++p) = '\0';
    return org_p;
}


/*--------------------------------------------------
* レスポンスを取得する。^\d\d\d- ならもう1行取得
*/
void read_response(int socket, char *p){
    do {
        read_line(socket, p);
        if ( debug_flg ){
            fprintf(stderr, "%s", p);
        }
    } while ( isdigit(p[0]) &&
             isdigit(p[1]) &&
             isdigit(p[2]) &&
             p[3]=='-' );
}


/*--------------------------------------------------
* 指定されたソケット socket に文字列 p を送信。
* 文字列 p の終端は \0 で terminate されている
* 必要がある
*/

void write_to_server(int socket, char *p){
    if ( debug_flg ){
        fprintf(stderr, "--> %s", p);
    }
    write(socket, p, strlen(p));
}

void error( char *message ){
    fprintf(stderr, "%s", message);
    exit(1);
}


int main(int argc, char *argv[]){
    int command_socket;           /* コマンド用ソケット */
    int data_socket;              /* データ用ソケット */
    int data_waiting_socket;          /* データコネクションの待ち受け用ソケット */
    struct hostent *servhost;         /* ホスト名とIPアドレスを扱うための構造体 */
    struct sockaddr_in server;        /* ソケットを扱うための構造体 */
    struct sockaddr_in sin;
    unsigned int len;

    char send_mesg[BUF_LEN];          /* サーバに送るメッセージ */
    char user[BUF_LEN] = "ユーザーネーム";               /* ftp サーバに送信するユーザ名 */
    char passwd[BUF_LEN] = "パスワード";             /* ftp サーバに送信するパスワード */
    char host[BUF_LEN] = "ホスト名";               /* 接続するホスト名 */
    char list[BUF_LEN] = "LIST";
    char buf[BUF_LEN];



    /* ホストの情報 (IP アドレスなど) を取得 */
    servhost = gethostbyname(host);
    if ( servhost == NULL ){
        fprintf(stderr, "Bad hostname [%s]\n", host);
        exit(1);
    }

    /* IP アドレスを示す構造体をコピー */
    bzero((char*)&server, sizeof(server));
    server.sin_family = AF_INET;

    /* 構造体をゼロクリア */
    bcopy(servhost->h_addr, (char *)&server.sin_addr, servhost->h_length);

    /* ポート番号取得 */
    server.sin_port = (getservbyname("ftp", "tcp"))->s_port;

    /* ソケット生成 */
    command_socket = socket(AF_INET, SOCK_STREAM, 0);

    /* サーバに接続 */
    connect(command_socket, (struct sockaddr *)&server, sizeof(server));

    /* welcome response を取得 */
    read_response(command_socket, buf);

    /* USER・PASS を送信 */
    sprintf(send_mesg, "USER %s\n", user);
    write_to_server(command_socket, send_mesg);
    read_response(command_socket, buf);

    sprintf(send_mesg, "PASS %s\n", passwd);
    write_to_server(command_socket, send_mesg);
    read_response(command_socket, buf);


    /* データコネクション用ソケットを作成し、
    * bind・listen する
    */
    data_waiting_socket = socket(AF_INET, SOCK_STREAM, 0);

    sin.sin_family = AF_INET;
    sin.sin_port = 0;
    sin.sin_addr.s_addr = htonl(INADDR_ANY);

    if ( bind(data_waiting_socket, (struct sockaddr *)&sin, sizeof sin) < 0 ){
        error("bind failed.\n");
    }
    if ( listen(data_waiting_socket, SOMAXCONN) == -1 ){
        error("listen failed.\n");
    }
    /* まだ accept はしない。PORT・LIST を送ってから */




    /* ----------------------------------------- */
    {
        u_long local_ip;

        /* localhost の IP アドレスを取得。既に ESTABLISHED である
        * command_socket から取得していることに注意。
        */

        len = sizeof(sin);
        if ( getsockname(command_socket,
                         (struct sockaddr *)&sin, &len) < 0 ){
            error("getsockname failed.\n");
        }
        local_ip = ntohl(sin.sin_addr.s_addr);

        /* ポート番号を取得 */
        if ( getsockname(data_waiting_socket,
                         (struct sockaddr *)&sin, &len) < 0 ){
            error("getsockname failed.\n");
        }

        sprintf(send_mesg, "PORT %d,%d,%d,%d,%d,%d\n",
                (int)(local_ip >> 24) & 0xff,
                (int)(local_ip >> 16) & 0xff,
                (int)(local_ip >>  8) & 0xff,
                (int)(local_ip)       & 0xff,
                /*
                * ↑は inet_ntoa(local_ip) でもいいんだけど、
                * その場合はピリオドをカンマに変換しないといけない。
                */
                (ntohs(sin.sin_port) >>  8) & 0xff,
                ntohs(sin.sin_port)        & 0xff);

        /* PORTを送信 */
        write_to_server(command_socket, send_mesg);
        read_response(command_socket, buf);

    }

    /* データコネクションの確立 */
    len = sizeof(sin);
    data_socket = accept(data_waiting_socket, (struct sockaddr *)&sin, &len);
    if ( data_socket == -1 ){
        error("accept failed.\n");
    }

    /*LISTを送信*/
    sprintf(send_mesg, "%s\n", list);
    write_to_server(command_socket, send_mesg);
    read_response(command_socket, buf);

    /* 150 Opening ASCII mode data connection ...
    * のようなレスポンスを受け取る
    */
    read_response(command_socket, buf);
    /* 226 Transfer complete. のようなレスポンスを受け取る */
    read_response(command_socket, buf);

    /* QUIT 送って終了 */
    write_to_server(command_socket, "QUIT\n");
    read_response(command_socket, buf);

    close(data_waiting_socket);
    close(command_socket);

    return 0;
}

試したこと

課題に対してアプローチしたことを記載してください

補足情報(言語/FW/ツール等のバージョンなど)

より詳細な情報

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正の依頼

  • matobaa

    2017/11/26 12:53

    作成しているFTPクライアントとFTPサーバの間にルータとか挟まってませんか? そこでNATしてませんか? FTPのPORTコマンドとNATは相性があまりよくないです。

    キャンセル

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.36%

関連した質問

同じタグがついた質問を見る

  • C

    2523questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • FTP

    235questions

    FTP(File Transfer Protocol)は、ネットワークでのファイル転送を行うための通信プロトコルの1つである。