-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

I looks like you've got a bit of a timing issue. The following is your code with correct timing. Note that I removed code unnecessary to the issue at hand.

Client: It looks like in the client, you were writing to the socket and immediately terminating the application (causing the connection to close). The doComms class was writing back to the client so I've added code to read the response. If, however, you were not expecting a response, you would still want to read in a byte. This will allow you to make sure you got the EOF rather than some data, and it blocks the current thread and keeps the connection alive.

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();
        }
    }
}

Server: I've changed the server to allow a maximum number of connections at any given time rather than shutting down after the maximum number of connections has been established. Also, note that I the threads are not daemons. If you want to serve X number clients then shutdown, you need a mechanism to allow the threads to continue executing before shutting down 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: Not much has changed with this class... I just cleaned it up a bit and removed unnecessary lines of code.

/*
 * 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();
    }
    }
}

Hope this helps :)

于 2012-07-25T03:34:25.007 回答
0

您的问题非常模糊,但是如果您想知道为什么服务器无法回复您的客户端,那是因为客户端从不从套接字读取。

于 2012-07-25T04:01:07.287 回答