2012-04-24 26 views
1

私はC#とクライアント/サーバープログラミングの両方に新しい。今、クラスでは、事前に設定されたFTPライブラリを使用せずにFTPクライアントを作成しようとしています。私は、ほとんどの部分のプロジェクトがダウンしているように感じるが、データポート(リスト、retrなど)の使用を必要とする複数の呼び出しを行うと問題に遭遇している。それが破壊されていますTcpClientをもう一度受け入れることができないC#

writer.WriteLine(portcmd); 
writer.Flush(); 

GetServerMessage(stream); 

writer.WriteLine("list "); 
writer.Flush(); 


tmpserver = new TcpListener(IPAddress.Any, 3128); 
tmpserver.Start(); 
tmpclient = tmpserver.AcceptTcpClient(); 
Console.WriteLine("gothere"); 

if (!tmpclient.Connected) 
{ 
    tmpserver.Start(); 
} 

StreamReader tmpreader = new StreamReader(tmpclient.GetStream()); 

GetServerMessage(stream); 
while (tmpreader.Peek() != -1) 
{ 
    Console.WriteLine(tmpreader.ReadLine()); 
} 

tmpclient.Close(); 
tmpserver.Stop(); 

GetServerMessage(stream); 

Getservermessageは、ネットワークストリームを取り、0.5秒のタイムアウト内で利用可能なすべてのものを出力する方法で、ストリームはFTPサーバへの現在の接続のためNetworkStreamで、作家は同じですStreamReaderでラップされたネットワークストリームを使用して、ASCII文字をサーバーに簡単に書き込むことができます。なぜ私はストリームリーダーを使用してデータ接続から読み取るのだろうかと疑問に思っている場合は、サーバーがデータを送信した後に接続を閉じて、簡単にeof通知を受け取ることができるからです。私のGetServerMessageメソッドは、何らかの理由で閉鎖されたネットワークストリームを使用したときに壊れていました。

このコードは、FTPサーバーにデータ接続が必要であることを通知するために、最初の2行を送信するようにポートコマンドを送信しています。次に、リストコマンドを送信し、サーバーへのデータ接続を確立し、次にデータ接続を終了します(コードの残りの部分)。

このコードは最初に実行したときに不具合なく実行されますが、もう一度試してみると 'tmpclient = tmpserver.AcceptTcpClient();'ライン。それは "gothere" printステートメントには決して達しません。私はこれが同じポート上の同じマシンからクライアントを受け取っていると確信していますが、わかりません。私は、AcceptTcpClient()が一度だけ実行されたことを確認するためにブール値を追加しようとしましたが、ランタイムエラーが発生し、Visual Studioに通知されました。一度それを閉じた後にサーバーが接続を再確立するかどうかはどうすればわかりますか?

私はtmpserverを停止し、tmpclientを閉じます。私は元々これをしました。なぜなら、FTPサーバーは、送信が完了したときにFTPサーバーが接続を閉じて、それが適切なことだと思っていたからです。私はこれらの行をコメントアウトすると、コードは複数回実行されますが、ストリームは空であるように見えます。この情報が役立つかどうかはわかりませんが、私はそれを言いたいと思いました。

不明な点がありましたらお詫び申し上げますが、この件に関する知識が不足しているため、問題を明確にすることができません。問題の内容に何か混乱があった場合、私はそれをクリアしようとしています。

答えて

3

あなたがtmpclient = tmpserver.AcceptTcpClient();を実行し、(第2のクライアントを受け入れる前に)その作品を仕上げるための最初のクライアントは良いアイデアではないかもしれないためにここで

はを待っサンプルサーバのコードで待機している必要があり、別のクライアントを受け入れることができるようにするには各クライアントから送信された文字列を接続してエコーします。あなたはtelnet localhost 3128

Thread t = new Thread(Server); 
t.IsBackground = true; 
t.Start(); 

でそれをテストすることができます - 私のコードで動作するように変化するのは少しで

void Server() 
{ 
    TcpListener listener = new TcpListener(IPAddress.Any, 3128); 
    listener.Start(); 
    while (true) 
    { 
     var client = listener.AcceptTcpClient(); 
     new Thread(() => 
     { 
      using (client) 
      { 
       var reader = new StreamReader(client.GetStream()); 
       var writer = new StreamWriter(client.GetStream()); 
       while (true) 
       { 
        string line = reader.ReadLine(); 
        if (line == "QUIT") break; 
        writer.WriteLine("From Thread[" + Thread.CurrentThread.ManagedThreadId + "] > " + line); 
        writer.Flush(); 
       } 
      } 
     }).Start(); 
    } 
} 
+0

、これは私の問題を修正ので、あなたに感謝しているようです!私は今「:すでに使用中のアドレスのデータ接続を構築することができません425」を述べFTPサーバから別のエラーを取得しています – Tom

0

OK、これはこのようなものです。簡単な方法でサーバーを実行するには、クライアントソケットを処理するコードをスレッドから外す必要があります。 acceptが返ってくると、スレッドを作成して開始し、 'tmpclient'を渡してから、新しいクライアントが接続できるように再度accept呼び出しにループします。新しく生成されたサーバー<>クライアントスレッドでは、渡されたソケットをクライアントで通信するためにループで読み書きします。

0

tcpクライアントストリームを閉じると、ストリームからプルしたストリームを読み取ることができなくなります。

var stream = tcpClient.GetStream(); 
... 
tcpclient.Close(); 
... 
stream.Read .. fail 

クライアントが別の接続を要求しなければならない、

OR

開いているあなたのTCPクライアントソケットを維持する必要があります。そして、クライアントがすぐに再接続しようとすると、サーバはスムーズに処理を続行することができます -

より複雑なサーバが突然クローズソケットときにクライアントに関するキャッシュされたいくつかのメタデータ(状態)を維持します。

関連する問題