Skip to content
Advertisement

Java socket client/server

Hi i am trying to get some data about a socket client connecting to a mutltythreaded server process in the same machine. The server thread is triggered correctly and the client ip is retreived ok, but i cant seem to be able to send a string through the connection. THE CLIENT

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

    }
}

THE SERVER THREAD

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

The line sent through is empty. CONNECTION ESTABLISHED

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

  }

}

Advertisement

Answer

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 🙂

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement