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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C

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

FTP

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

Q&A

2回答

11671閲覧

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

shunichi1104

総合スコア7

C

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

FTP

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

0グッド

1クリップ

投稿2017/11/26 02:14

###前提・実現したいこと
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/ツール等のバージョンなど)
より詳細な情報

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

matobaa

2017/11/26 03:53

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

回答2

0

どこで止まっているかわかりますか?

デバッグオプションをつけてコンパイルして、デバッガの上で動かしてみるか、止まったらシグナルを投げ込んでcore吐かせて、それをデバッガに食わせてみると、何かわかるかもしれません。

投稿2017/12/15 10:05

matobaa

総合スコア2493

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

matobaa

2017/12/15 10:19

って、こんなこと言っても、まずは用語がわからんだろうなーと思いながら書いてます。わからんかったらちょっと調べてみて、それでもわからんかったらまた聞けばよろしい。
matobaa

2017/12/15 10:22

おっと……Xcodeを使ってるんですね。なんかもうちょっといいやり方がありそうな気もします。
guest

0

「write() が成功して返ってきても、データがディスクに記録されたことを 保証するものではない。 実際、データのためのスペースが確保されたことすら保証されないという バグっぽい実装もある。 これを確実にする唯一の方法は、 全てのデータを write した後に fsync(2) を呼び出すことである。」
ってman のページにあります。

投稿2017/12/14 09:10

gm300

総合スコア580

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問