- PR -

ftpへの接続について

1
投稿者投稿内容
shima
会議室デビュー日: 2004/03/11
投稿数: 5
投稿日時: 2004-03-11 21:54
はじめまして。
初心者です。

FTPを使ってファイルを転送するプログラムを作っているのですがうまくいきません。

openの部分はうまくいっているようなのですが、userを入力するコマンドを送信するところで止まってしまい数分後にエラーになってしまいます。

いろいろとサイトを調べたのですがVBのサンプルが見当たらなかったので、C#のサンプルを参考にして作っているのですが、C#もほとんどわからないのでどこが悪いのかよくわかりません。

初歩的なことで申し訳ありませんが、よろしくお願い致します。

以下ソースです。

Public Function Connect() As Integer
 Dim ResponseCode As String
 Dim HostAddress As IPHostEntry = Dns.Resolve(FtpServer)
 Dim IPAddr As IPAddress = HostAddress.AddressList(0)
 Dim IPServer As IPEndPoint = New IPEndPoint(IPAddr, mPort)
 Try
  mClientSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
  mClientSocket.Connect(IPServer)
  Dim RecvData(256) As Byte
  RecvData.Initialize()
  mClientSocket.Receive(RecvData)
  Dim ResponseData As String = System.Text.Encoding.ASCII.GetString(RecvData)

 'ResponseDataの中身→ (220 サーバ名 Microsoft FTP Service (Version 2.0).)
  Dim cmd As String
  Dim Output As String = Nothing
  Dim retCode As Integer = 0

  cmd = "user " & UserID & "\\r\\n"
  retCode = ExecCmd(cmd, Output)
(省略)

Private Function ExecCmd(ByVal cmd As String, ByVal outputData As String) As Integer
 Dim sendData(512) As Byte
 Dim recvData(1024) As Byte

 sendData = System.Text.Encoding.ASCII.GetBytes(cmd)
 If mClientSocket.Send(sendData) <> sendData.Length Then
  Return 0
 End If
 Dim sb As New StringBuilder
 recvData.Initialize()
 Do Until mClientSocket.Receive(recvData) = 0 ←ここでとまってしまいます
  sb.Append(System.Text.Encoding.ASCII.GetString(recvData))
  If mClientSocket.Available = 0 Then
   Exit Do
  End If
 Loop
 outputData = sb.ToString
 Return 1
End Function
なな
ぬし
会議室デビュー日: 2003/06/22
投稿数: 659
お住まい・勤務地: 愛知県
投稿日時: 2004-03-11 22:40
引用:

cmd = "user " & UserID & "\\r\\n"



推測ですが...CR+LFのコードがおかしいのでは?

cmd = "USER " & UserID & Chr(13) & Chr(10)
でどうでしょう?

shima
会議室デビュー日: 2004/03/11
投稿数: 5
投稿日時: 2004-03-12 09:43
返答ありがとうございます。

引用:


推測ですが...CR+LFのコードがおかしいのでは?

cmd = "USER " & UserID & Chr(13) & Chr(10)
でどうでしょう?




CR+LFのコードを変えたところ進みました。
VB.NETで改行するという情報を送る必要があったのですね。
C#の方で"\r\n"と書いてあったのでコマンドで実行する際に改行するのかと思っていました。

ありがとうございました。
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2004-03-12 09:57
"\"はC#で文字列定数の中で特殊な文字を表すときに使われるエスケープ文字ですね。
VB.NETでは Chr(13) & Chr(10) もいいですけどvbCrLfという定数もありますよ。

cmd = "USER " & UserID & vbCrLf

こうします。
KAN
常連さん
会議室デビュー日: 2003/05/09
投稿数: 27
投稿日時: 2004-05-14 19:54
こんにちは。

STORの使い方(便乗質問ですみません)

引用:
--------------------------------------------------------------------------------

cmd = "user " & UserID & "\\r\\n"
retCode = ExecCmd(cmd, Output)

--------------------------------------------------------------------------------

ファイルをFTPサーバーに転送する時に
reqMsg = "STOR c:\tmp\hoge.gif" & ControlChars.CrLf
retCode = ExecCmd(cmd, Output)
を使ったのですが、エラーとなってしまいました。
エラーコード:
550 c:\tmp\hoge.gif: The filename, directory name, or volume label syntax is incorrect.

[c:\hoge.gif]ファイルが存在し、下記のように記述してやれば、うまくいきます。
reqMsg = "STOR hoge.gif" & ControlChars.CrLf
retCode = ExecCmd(cmd, Output)

remotehelp コマンドで調べて見ましたが、
(STOR STOU STRU XCWD・・・)
パスを指定して、ファイル転送する方法が見つかりませんでした。

ぜひご教授ください。
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2004-05-15 01:06
エラーメッセージに書かれているとおり「550 c:\tmp\hoge.gif: The filename, directory name, or volume label syntax is incorrect. 」が原因ですよ。FTPのコマンドには通常パス名を指定してファイルを転送するコマンドはありませんよ。CDやLCDでフォルダを移動した後、PUTしますよね。

SocketベースでFTPを実装しようとしているのには何か理由があるのでしょうか?Socketベースで作ろうとしているなら、最低限RFCぐらいは読んで理解してないと無理です。でもそのわりに質問内容から推測するに、いったい何を参考にして作っているのか理解に苦しみます。

手を抜くならWinInet APIをラップした方が手っ取り早いと思うんですが。
KAN
常連さん
会議室デビュー日: 2003/05/09
投稿数: 27
投稿日時: 2004-05-17 09:35
おはようございます。
ご回答、ありがとうございました。

もう少し調べれば、よかったんですが、
反省してます。

SocketベースでFTPを実装しようとしているのは、一応勉強したかったからです。
で、確かに通常パス名を指定してファイルを転送するコマンドはありません。
それと、コマンドLCDのようなものもありません。

解決方法:
'--- ポートコネクション
reqMsg = "PASV" & ControlChars.CrLf
retCode = ExecCmd(cmd, Output)
'--- 通常パス名を指定してファイルを転送
reqMsg = "STOR " & Path.GetFileName(cFileArr(i)) & ControlChars.CrLf
retCode = ExecCmd(cmd, Output)
'--- 終了処理
reqMsg = "QUIT" & ControlChars.CrLf
retCode = ExecCmd(cmd, Output)
1

スキルアップ/キャリアアップ(JOB@IT)