-1

こんにちは私は同じマシンのマルチスレッドサーバープロセスに接続しているソケットクライアントに関するデータを取得しようとしています。サーバースレッドは正しくトリガーされ、クライアントIPは正常に取得されますが、接続を介して文字列を送信できないようです。クライアント

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package solverapplet;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.io.*;

/**
 *
 * @author me
 */
public class Solverapplet {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        Socket s;
        try {
            s = new Socket("IP", 4445);
            System.out.println(s.getPort());
            //DataInputStream in = new DataInputStream (s.getInputStream());
       BufferedWriter out = new BufferedWriter(
                            new OutputStreamWriter(s.getOutputStream()));
        out.write("gamma");
                        out.newLine();
                        out.flush();

        } catch (UnknownHostException ex) {
            Logger.getLogger(Solverapplet.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Solverapplet.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
}

サーバースレッド

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package serversideserver;
import java.io.*;
import java.net.*;
import java.security.*;
import java.util.List;
import java.sql.*;
import com.google.gson.Gson;


class doComms implements Runnable {
    private Socket server;

    private String line,input,ip;

    doComms(Socket server, String ip) {
      this.server=server;
      this.ip=ip;
    }

    public void run () {

      input="";

      try {
        // Get input from the client
        BufferedReader in = new BufferedReader(
                            new InputStreamReader(server.getInputStream()));

        PrintStream out = new PrintStream(server.getOutputStream());
      Connection conn = null;
        try
           {
               String userName = "root";
               String password = "";
               String url = "jdbc:mysql://localhost/test";
               Class.forName ("com.mysql.jdbc.Driver").newInstance ();
               conn = DriverManager.getConnection (url, userName, password);
               System.out.println ("Database connection established");
               // create the java statement
      Statement st = conn.createStatement();

       // ResultSet rs;
        while((line = in.readLine()) != null && !line.equals(".")) {
            // Now do the magic.
       //Data data = new Gson().fromJson(line, Data.class);
       System.out.println("LINE: " + line);
        input=line;
        st.executeUpdate("UPDATE `solvers` SET `online`='1',`ip`='"+  server.getInetAddress().toString().substring(1) +"' WHERE `user`='"+ line +"'");

         // input= data.getcmd();
          out.println("{\"captcha\":1,\"text\":\"abc\",\"is_correct\":\"true\"}");
        } 
           }
           catch (Exception e)
           {
               System.out.println (e.toString());
           }

        // Now write to the client

        System.out.println("UPDATE `solvers` SET `online`='1',`ip`='"+  server.getInetAddress() +"' WHERE `user`='"+ input +"'");
        //out.println("Overall message is:" + input);

        server.close();
      } catch (IOException ioe) {
        System.out.println("IOException on socket listen: " + ioe);
        ioe.printStackTrace();
      }
    }
}

送信された行は空です。接続が確立されました

package serversideserver;

import java.io.*;
import java.net.*;
import java.security.*;
import java.sql.*;
/**
 * Title:        Sample Server
 * Description:  This utility will accept input from a socket, posting back to the socket before closing the link.
 * It is intended as a template for coders to base servers on. Please report bugs to brad at kieser.net
 * Copyright:    Copyright (c) 2002
 * Company:      Kieser.net
 * @author B. Kieser
 * @version 1.0
 */

public class Serversideserver {

  private static int port=4445,portsolver=4445, maxConnections=0;
  // Listen for incoming connections and handle them
  public static void main(String[] args) {
    int i=0;

    try{
      ServerSocket listener = new ServerSocket(port);
      Socket server;

      long counter=0;
             int counter1=0;
     int id=0;
      String ip="uninit";
      while((i++ < maxConnections) || (maxConnections == 0)){

        server = listener.accept();
        counter++;
      doComms conn_c= new doComms(server,ip);
        Thread t = new Thread(conn_c);
        t.start();
        //System.out.println("counter "+ (counter % id) );
      }
    } catch (IOException ioe) {
      System.out.println("IOException on socket listen: " + ioe);
      ioe.printStackTrace();
    }

  }

}
4

2 に答える 2

1

タイミングに少し問題があるようです。以下は、正しいタイミングのコードです。手元の問題に不要なコードを削除したことに注意してください。

クライアント:クライアントでは、ソケットに書き込みを行っていて、すぐにアプリケーションを終了していたようです(接続を閉じます)。doCommsクラスがクライアントに書き戻していたので、応答を読み取るためのコードを追加しました。ただし、応答を期待していなかった場合でも、バイト単位で読み取りたいと思うでしょう。これにより、一部のデータではなくEOFを確実に取得できるようになり、現在のスレッドがブロックされ、接続が維持されます。

package solverapplet;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.io.*;

/**
 *
 * @author you
 */
public class Solverapplet {

    /**
     * @param args the command line arguments
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
        Socket s = null;
        try {
            // make connection
            s = new Socket("localhost", 4445);

            // define streams
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
            BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));

            // write data
            out.write("gamma");
            out.newLine();
            out.flush();

            // read response
            String returnData = in.readLine();
            System.out.println(returnData);

        } catch (UnknownHostException ex) {
            Logger.getLogger(Solverapplet.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Solverapplet.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            // close connection
            s.close();
        }
    }
}

サーバー:最大接続数が確立された後にシャットダウンするのではなく、常に最大数の接続を許可するようにサーバーを変更しました。また、スレッドはデーモンではないことに注意してください。X番号のクライアントにサービスを提供してからシャットダウンする場合は、ServerSocketをシャットダウンする前にスレッドの実行を継続できるようにするメカニズムが必要です。

package serversideserver;

import java.io.*;
import java.net.*;

/**
 * Title:        Sample Server
 * Description:  This utility will accept input from a socket, posting back to the socket before closing the link.
 * It is intended as a template for coders to base servers on. Please report bugs to brad at kieser.net
 * Copyright:    Copyright (c) 2002
 * Company:      Kieser.net
 * @author B. Kieser
 * @version 1.0
 */

public class Serversideserver {

    private static int port             =4445;
    private static int maxConnections   =10;

    private static int connections = 0;

    synchronized static void connectionClosed() {
        connections--;
        Serversideserver.class.notify();
    }

    /**
     * The blocking mechanism to only allow <code>maxConnections<code> 
     * @throws InterruptedException
     *      thrown if blocking thread is interupted
     */
    private synchronized static void nextConnection() throws InterruptedException {
        while(connections>=maxConnections) {
            Serversideserver.class.wait();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        try{
            // server socket
            ServerSocket listener = new ServerSocket(port);
            // socket
            Socket socket;

            // Keep the server alive
            while(true){
                // Blocks if we have reached the max
                nextConnection();

                // Accept connection to client
                socket = listener.accept();

                // define request service
                doComms conn_c= new doComms(socket,socket.getInetAddress().getCanonicalHostName());
                Thread t = new Thread(conn_c);
                t.setDaemon(false);

                // run request service
                t.start();
            }
        } catch (IOException ioe) {
            System.out.println("IOException on socket listen: " + ioe);
            ioe.printStackTrace();
        }
    }
}

doComms:このクラスではあまり変更されていません...少しクリーンアップして、不要なコード行を削除しました。

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package serversideserver;
import java.io.*;
import java.net.*;


class doComms implements Runnable {
    private Socket socket;
    private String ip;

    doComms(Socket socket, String ip) {
        this.socket = socket;
        this.ip = ip;
    }

    public void run () {
        try {
            // Define input/output
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintStream out = new PrintStream(socket.getOutputStream());

            // Process requests until the EOF is found
            String line;
            while((line = in.readLine()) != null && !line.equals(".")) {
                // print input
                System.out.println("LINE: " + line);

                // print process line
                System.out.println("UPDATE `solvers` SET `online`='1',`ip`='"+  ip +"' WHERE `user`='"+ line +"'");

                // write response
                out.println("{\"captcha\":1,\"text\":\"abc\",\"is_correct\":\"true\"}");
            }

            socket.close();
        } catch (IOException ioe) {
            System.out.println("IOException on socket listen: " + ioe);
            ioe.printStackTrace();
        } finally {
        Serversideserver.connectionClosed();
    }
    }
}

お役に立てれば :)

于 2012-07-25T03:34:25.007 に答える
0

あなたの質問は非常に曖昧ですが、なぜサーバーがクライアントに応答できないのか疑問に思っているのなら、それはクライアントがソケットから読み取ることがないためです。

于 2012-07-25T04:01:07.287 に答える