2011-07-25 27 views
2

私はクライアントと通信するサーバーを持っています。ストリームが閉じられない限り、BufferedWriterはテキストを送信しません。

サーバーがマルチスレッド化されている、そしてこのスレッドがソケットとソケットに接続をBufferedReaderを使用して作成され、ソケットから読み取る最初の行は「要求」のとき:

public class scriptComm implements Runnable { 

private Socket sock; 
private Socket sock2; 
private Connection connection; 
private BufferedReader reader; 

@Override 
public void run() { 
    try { 

     String name = reader.readLine(); 
     String password = reader.readLine(); 

     String line; 
     connection = methods.connectToDatabase(); 
     BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream())); 
     if (connection != null && name != null && password != null) { 
      try { 
       ResultSet rs = connection.createStatement().executeQuery(
         "SELECT name, password, doupdate FROM accounts " 
         + "WHERE name = '" + name + "' AND doupdate = 'yes'" 
         + " AND password = '" + password + "'"); 
       if (rs.next()) { 
        methods.log("worked"); 
        bw.write("accept"); 
        bw.flush(); 
        bw.close(); 
        reader = new BufferedReader(new InputStreamReader(sock2.getInputStream())); 
        if ((line = reader.readLine()) != null) { 
         mainFrame.jTextArea1.append("line \n"); 
         connection.createStatement().executeUpdate(
           "UPDATE accounts SET updatetext = '" + line + "' " 
           + "WHERE name = '" + name + "'"); 
        }else{ 
         mainFrame.jTextArea1.append("No text received \n"); 
        } 
       } else { 
        bw.write("decline"); 
        bw.flush(); 
       } 
       bw.close(); 
       rs.close(); 
      } catch (SQLException ex) { 
       methods.log("Error when executing statement in scriptComm"); 
       ex.printStackTrace(); 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 
     } else { 
      methods.log("missing values in scriptComm"); 

     } 
    } catch (IOException ex) { 
    } 


} 

public scriptComm(Socket sock, BufferedReader reader) { 
    this.sock = sock; 
    this.sock2 = sock; 
    this.reader = reader; 
}} 

あなたはそのI気づくかもしれ"accept"を書き込んだ後にbwストリームを閉じます。

これは、クライアントがストリームを閉じていないときに入力を受信しないかのように単純にハングしているためです。

クライアント:。

 try{ 
     String line; 
     Socket sock = new Socket("myipaddresshere",portnumber); 
     PrintWriter writer = new PrintWriter(sock.getOutputStream()); 
     BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream())); 
     writer.println("script"); 
     writer.flush(); 
     writer.println(jTextField1.getText()); 
     writer.flush(); 
     writer.println(jTextField2.getText()); 
     writer.flush(); 
     if ((reader.readLine()).equals("accept")) { 
      writer.write("testing123"); 
      writer.flush(); 
      writer.close(); 
     } else { 
      jTextArea1.append("fail"); 

     } 
     reader.close(); 
     writer.close(); 
    }catch(IOException e){ 
     jTextArea1.append("Server not available. Please try again later."); 
    } 

ストリームは、サーバーから「受け入れる」の書き込み後にクローズされていない場合は、クライアントがあるかの(reader.readLine()に座っているかのように、それはだ等号(「受け入れます"))boolean check(そしてyes、ストリームはサーバー側でフラッシュされます)。

しかし、ストリームがサーバー側でも閉じられている場合、ブールチェックに合格し、引き続きストリーム "testing123"に書き込みます。 BufferedReaderが閉じられたとき、ソケットストリームが閉じられたので、サーバーは明らかにこの行を読み取ることができません。ご存じのように、私はsock2という別の変数を作成するだけでソケットを複製しようとしましたが、この接続も閉じているようです(意味があります)。

注:間違ったユーザー/パスで接続した場合(つまり、rs.next()がfalseを返す場合)、ストリームに「拒否」と書き込まれ、クライアントはこれを取得します。この約1本当に混乱し

..

おかげで、 マイク。

答えて

3

注意書き出しは改行を書き込まないので、行全体を読み込もうとしています。フラッシュする前に改行文字を書く必要があります。

EditherはBufferedWriterを使用します。 newLine()、または書き込む文字列に"\n"を追加します。

+0

私はそれを見つけなかったので、愚かなようです:p。ありがとう。 また、SQLインジェクションを防ぐことについてどこから読んで始めたらよいでしょうか? –

+1

Googleでそれを実行する必要がありますが、これはパラメータ付きで 'PreparedStatement'に切り替えることです。そのJavaクラスはあなたのためにエスケープ処理を行います。二重引用符または一重引用符はもはや問題にはなりません。 – Kaj

+0

この記事では、この問題を回避する方法について説明します。https://www.owasp.org/index.php/Preventing_SQL_Injection_in_Java – Kaj

2

私がアドバイス断片と引き込まれ、これを残しておきます:

あなたがストリームに文字を書きたいときに、あなたは常に明示的な文字エンコーディングをOutputStreamWriterInputStreamReaderを使用する必要があります。私は「UTF-8」をお勧めします。

書かれているように、あなたのコードは、プラットフォームのデフォルトエンコーディングで書込みと読取りの両方を行います。これはうまくいくでしょう。あなたが中国でクライアントをWindows上で走らせ、米国内でLinux上でサーバを稼動させている人がいるまで(そしてあなたが送るものによっては、ずっと早く破損する可能性があります)

+0

これは問題ではないですが、問題は彼が 'readLine()'を使っていて、サーバが改行を書いていないことです。 – Kaj

+0

@カイ - ええ、私はタイトルに基づいて答え、その後、コード内のすべてのフラッシュを見た。 – parsifal

+0

私は彼に別のアドバイスを与えることができます。データベースコードを変更すると、それはSQLインジェクション攻撃に開放されています:) – Kaj

関連する問題