Java套接字客户端/服务器

时间:2012-07-25 01:18:19

标签: java sql sockets client

您好我正在尝试获取有关连接到同一台机器中的mutltythreaded服务器进程的套接字客户端的一些数据。服务器线程被正确触发,客户端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();
    }

  }

}

2 个答案:

答案 0 :(得分: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();
    }
    }
}

希望这会有所帮助:)

答案 1 :(得分:0)

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