0

I have these three classes, TCPClient, TCPServer and Member. I am using TCPClient to send RequestPacket object to TCPServer, which then responds back with a string to TCPClient. Here's the code:

TCPServer

import java.io.*;
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.io.ObjectInputStream.GetField;
import java.net.*;

import data.RequestPacket;
public class TCPServer {
private static LinkedHashMap<Integer,String> port_database_map = new LinkedHashMap();
static{
    port_database_map.put(2131,"testing1");
    port_database_map.put(6789, "testing2");

}
public static void main(String[] args) throws Exception {
    if(args.length==1){
    String clientSentence;
    String capitalizedSentence;
    new TCPServer().sqlConnectionTest();

    ServerSocket welcomeSocket = new ServerSocket(Integer.parseInt(args[0]));

    System.out.println("Server running at "+welcomeSocket.getLocalSocketAddress()+" and port "+welcomeSocket.getLocalPort());
    Socket connectionSocket = welcomeSocket.accept();
    InputStream is = connectionSocket.getInputStream();
    ObjectInputStream ois = new ObjectInputStream(is);
    DataOutputStream outToClient;
    //DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
    while(true){

    //  BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));

        outToClient = new DataOutputStream(connectionSocket.getOutputStream());
        //clientSentence = inFromClient.readLine();
        RequestPacket rp = (RequestPacket) ois.readObject();
        outToClient.writeUTF(rp.query);
        outToClient.flush();
        System.out.println("Received object "+rp.query);
        //System.out.println("Client sentence is "+clientSentence);
        //capitalizedSentence = getClientResponse(clientSentence);
    //  outToClient.writeBytes(getClientResponse(clientSentence));


    }
    } else{
        System.out.println("Enter port numnber as argument");
        System.exit(1);
    }
}

public static String getClientResponse(String clientRequest){

    return clientRequest.toUpperCase().trim()+'\n';
}

public void sqlConnectionTest(){
    String sqlString;
    try{
        Class.forName("com.mysql.jdbc.Driver");
        System.out.println("MySQLJDBC Driver registered");
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:8889/testing1","root","root");
        if(connection!=null){
            System.out.println("You made it!");

        }else
            System.out.println("Connection failed");
    }catch(ClassNotFoundException e){
        System.out.println("Where is your mySQL JDBC Driver? "+e);

    }catch(SQLException e){
        System.out.println("Caught SQLException "+e);
    }
}
}

TCPClient

import java.io.*;
import java.net.*;
import java.util.Scanner;

import data.RequestPacket;
import data.RequestPacket.RequestType;
public class TCPClient {
public static void main(String[] args) throws UnknownHostException, IOException {
    if(args.length==1){
    String sentence;
    String modifiedSentence;

    //BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
    Socket clientSocket = new Socket("0.0.0.0",Integer.parseInt(args[0]));
    String query = "SELECT * FROM NOTHING";
    //Scanner in = new Scanner(System.in);
    DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
    RequestPacket rp = new RequestPacket(Integer.parseInt(args[0]), query, RequestType.NEW_REGISTRATION);
    OutputStream os = clientSocket.getOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(os);
    /*while(in.hasNextLine())*/if(rp.port!=0){
        DataInputStream inFromServer = new DataInputStream(clientSocket.getInputStream());
        //sentence = in.nextLine();

        //sentence = "Hello, this is Rohan";
        System.out.println("Sentence is "+rp);
        oos.writeObject(rp);
        //outToServer.writeUTF(rp+"\n");
        //outToServer.writeBytes(sentence+"\n");
        oos.flush();
        modifiedSentence = inFromServer.readLine();
        System.out.println("DONE");
        System.out.println("FROM SERVER: "+modifiedSentence);

        //outToServer.flush();
    }
    oos.close();
    os.close();
    clientSocket.close();
}else{
    System.out.println("Enter port for client to connect to");
    System.exit(1);
}
}
}

RequestPacket /* */ package data;

import java.io.Serializable;

/**
 * @author rohandalvi
 *
 */
public class RequestPacket implements Serializable {
    public int port;
    public String query;
    public RequestType type;
    public enum  RequestType{
        NEW_REGISTRATION,IN_TRANSIT_SCAN,REPLICATION,DELETE_MEMBERSHIP,REMOVE_BENEFICIARY
    }

    public RequestPacket(int port, String query,RequestType type){
        this.port = port;
        this.query = query;
        this.type = type;
    }

}

When I run client, it sends the RequestPacket object to TCP server, but for some reason, the TCPServer does not respond back with the rp.query value to the client. It does so, only when I stop the server, I immediately see the Server response printed on the client side.

Please help if you know what's wrong. Thanks.

Rohan Dalvi
  • 1,215
  • 1
  • 16
  • 38
  • You have a sensible application-layer protocol for the client-to-server direction, Java's object stream protocol. But I don't see any application-layer protocol in the other direction. So how does the client know when it should process the data? (Other than when you stop the server, of course.) TCP 101 -- you must implement a protocol on top of TCP -- it won't work by magic. – David Schwartz Jun 19 '14 at 05:56
  • It doesn't help that you've got a lot of commented out code, along with other code that's irrelevant to the question. There's also missing code, such as `RequestPacket`. Please try to reduce your code to a short but *complete* program that demonstrates the problem but has nothing else in it. – Jon Skeet Jun 19 '14 at 05:56
  • was the rp.query successfully printed in your server side? – Rod_Algonquin Jun 19 '14 at 06:00
  • Did you try with adding a getter for the query property? I experienced it in RPC clients. – malintha Jun 19 '14 at 06:13

2 Answers2

0

Instead of passing the InputStream to the BufferedReader, just directly reference it to DataInputStream and read the UTF from there.

sample:

      DataInputStream inFromServer = new DataInputStream(clientSocket.getInputStream());
      modifiedSentence = inFromServer.readUTF();
Rod_Algonquin
  • 26,074
  • 6
  • 52
  • 63
  • didn't help . I updated the code above to reflect the changes I made. – Rohan Dalvi Jun 19 '14 at 06:15
  • Exception in thread "main" java.io.EOFException at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2601) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1319) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371) at TCPServer.main(TCPServer.java:38) – Rohan Dalvi Jun 19 '14 at 06:28
  • @RohanDalvi you are in a while loop inside your server so when the client quits the server is still reading the response from the client which already closed – Rod_Algonquin Jun 19 '14 at 06:31
  • @RohanDalvi did the it print in the client side? – Rod_Algonquin Jun 19 '14 at 06:33
  • no, it did not print in the client side. It did on the server side – Rohan Dalvi Jun 19 '14 at 18:33
0

Just following Jon Skeet's advice from the comments (reduce the code to a short but complete program) and using the answer from Rod_Algonquin, I'm left with a program that has no problem. Add more code and keep testing after each change to see when the program breaks so you can find what code is giving you trouble.

public class NetworkObjectString {

public static void main(String[] args) {

    Socket s = null;
    try {
        new Thread(new TcpServer()).start();
        // Wait for socket server to start
        Thread.sleep(500);
        // TcpClient
        s = new Socket(InetAddress.getLocalHost(), 54321);
        RequestPacket rp = new RequestPacket();
        rp.port = 123;
        rp.query = "dummy query";
        ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
        oos.writeObject(rp);
        oos.flush();
        System.out.println("Client send rp.query: " + rp.query);
        DataInputStream dis = new DataInputStream(s.getInputStream());
        String sq = dis.readUTF();
        System.out.println("Client received query: " + sq);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try { s.close(); } catch (Exception ignored) {}
    }
}

static class TcpServer implements Runnable {

    public void run() {

        ServerSocket ss = null;
        Socket s = null;
        try {
            s = (ss = new ServerSocket(54321)).accept();
            ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
            RequestPacket rp = (RequestPacket) ois.readObject();
            System.out.println("Server received rp: " + rp);
            String sq = rp.query + " from server";
            DataOutputStream dos = new DataOutputStream(s.getOutputStream());
            dos.writeUTF(sq);
            dos.flush();
            System.out.println("Server send query: " + sq);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try { ss.close(); } catch (Exception ignored) {}
            try { s.close(); } catch (Exception ignored) {}
        }
    }
} // TcpServer

static class RequestPacket implements Serializable {

    private static final long serialVersionUID = 1082443947105396312L;

    public String query;
    public int port;

    public String toString() { return port + " - " + query; }
}

}
Community
  • 1
  • 1
vanOekel
  • 6,358
  • 1
  • 21
  • 56
  • I get EOFException with this code. I think it is because the readUTF() – Rohan Dalvi Jun 19 '14 at 21:33
  • @RohanDalvi I cannot reproduce that. At which line does the exception occur? – vanOekel Jun 19 '14 at 21:45
  • EOF Exception java.io.EOFException at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2601) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1319) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371) at TCPServer.main(TCPServer.java:38) `RequestPacket rp = (RequestPacket) ois.readObject();` – Rohan Dalvi Jun 20 '14 at 02:18
  • @RohanDalvi So that is at the first time the server tries to read data from the connection, but for some reason the connection is already closed (on client side). Did you see the output `Client send rp.query ...`? If you are writing/reading in a loop, check the answer and comments in [this question](http://stackoverflow.com/q/12684072/3080094). – vanOekel Jun 20 '14 at 09:20