0

I'm trying to implement a simple TCP connection between Client/Server. I made the Server multithreaded so that it can take either multiple requests (such as finding the sum, max, min of a string of numbers provided by the user) from a single client or accept multiple connections from different clients. I'm running both of them on my machine, but the server doesn't seem to push out an answer. Not sure what I'm doing wrong here --

public final class CalClient {

static final int PORT_NUMBER = 6789;  

public static void main (String arg[]) throws Exception
{
    String serverName;
    @SuppressWarnings("unused")
    String strListOfNumbers = null;
    int menuIndex;
    boolean exit = false;

    BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));

    System.out.println("Please enter host name...");
    System.out.print("> ");
    serverName = inFromUser.readLine();

    Socket clientSocket = new Socket(serverName, PORT_NUMBER);
    DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
    BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

    //outToServer.writeBytes(serverName + '\n');

    System.out.println("");
    System.out.println("Enter 1 to enter the list of numbers");
    System.out.println("Enter 2 to perform Summation");
    System.out.println("Enter 3 to calculate Maximum");
    System.out.println("Enter 4 to calculate Minimum");
    System.out.println("Enter 5 to Exit");

    while (!exit) {
        System.out.print(">");
        menuIndex = Integer.parseInt(inFromUser.readLine());

        if (menuIndex == 1) {   
            System.out.println("Please enter the numbers separated by commas.");
            System.out.print(">");
            strListOfNumbers = inFromUser.readLine();
            outToServer.writeBytes("List" + strListOfNumbers);
            //continue;
        }
        else if (menuIndex == 2) {
            outToServer.writeBytes("SUM");
            System.out.println(inFromServer.readLine());
        }
        else if (menuIndex == 3) {
            outToServer.writeBytes("MAX");
            System.out.println(inFromServer.readLine());
        }
        else if (menuIndex == 4) {
            outToServer.writeBytes("MIN");
            System.out.println(inFromServer.readLine());
        }
        else if (menuIndex == 5) {
            outToServer.writeBytes("EXIT");
            exit = true;
        }
    }
}

}

public final class CalServer 
{

      static final int PORT_NUMBER = 6789;  

public static void main(String[] args) throws IOException 
{
    try {
        ServerSocket welcomeSocket = new ServerSocket(PORT_NUMBER);
        System.out.println("Listening");
        while (true) {
            Socket connectionSocket = welcomeSocket.accept();

            if (connectionSocket != null) {
                CalRequest request = new CalRequest(connectionSocket);
                Thread thread = new Thread(request);
                thread.start();
            }
        }
    } catch (IOException ioe) {
        System.out.println("IOException on socket listen: " + ioe);
        ioe.printStackTrace();
    }
}
}

final class CalRequest implements Runnable
{
Socket socket;
BufferedReader inFromClient;
DataOutputStream outToClient;

TreeSet<Integer> numbers = new TreeSet<Integer>();
int sum = 0;

public CalRequest(Socket socket)
{
    this.socket = socket;
}

@Override
public void run() 
{
    try {
        inFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
        outToClient = new DataOutputStream(socket.getOutputStream());

        while(inFromClient.readLine()!= null) {
            processRequest(inFromClient.readLine());
        }       

    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void processRequest(String string) throws IOException
{
    String strAction = string.substring(0,3);

    if (strAction.equals("LIS")) {
        String strNumbers = string.substring(5);
        String[] strNumberArr;
        strNumberArr = strNumbers.split(",");

        // convert each element of the string array to type Integer and add it to a treeSet container. 
        for (int i=0; i<strNumberArr.length; i++)
            numbers.add(new Integer(Integer.parseInt(strNumberArr[i])));
    }
    else if (strAction.equals("SUM")) {
        @SuppressWarnings("rawtypes")
        Iterator it = numbers.iterator();
        int total = 0;

        while (it.hasNext()) {
            total += (Integer)(it.next());
        }
    }
    else if (strAction.equals("MAX")) {
        outToClient.writeBytes("The max is: " + Integer.toString(numbers.last()));
    }
    else if (strAction.equals("MIN")) {
        outToClient.writeBytes("The max is: " + Integer.toString(numbers.first()));
    }
}

}

2
  • not a question to be found... Commented Jul 22, 2011 at 0:05
  • Sorry, I was editing it. Commented Jul 22, 2011 at 0:12

2 Answers 2

1

Since you are using readLine(), I would guess that you actually need to send line terminators.

Sign up to request clarification or add additional context in comments.

4 Comments

You mean a carriage-return/line-feed sequence ("\r\n"), a single carriage-return ("\r"), or a single line-feed ("\n")? So would I be concatinating it when I'm writing bytes to the server?
I added \r\n to the client side but made no difference. And when I entered 3 for MAX, it throws the following expception Exception in thread "Thread-0" java.util.NoSuchElementException at java.util.TreeMap.key(Unknown Source) at java.util.TreeMap.lastKey(Unknown Source) at java.util.TreeSet.last(Unknown Source) at CalRequest.processRequest(CalServer.java:84) at CalRequest.run(CalServer.java:53) at java.lang.Thread.run(Unknown Source)
45 views but no answer, great.
The other thing that usually causes this is that you need to flush the sockets after writing something. Otherwise it will just wait for more data to arrive so it can all be sent in a large bunch. I really don't know if this is the problem here; some environments flush automatically upon encountering newline characters, but it is definitely worth a try.
1

My experience with TCP socket communications uses ASCII data exclusively, and my code reflects that I believe. If that's the case for you, you may want to try this:

First, try instantiating your data streams like this:

socket     = new Socket (Dest, Port);
toServer   = new PrintWriter (socket.getOutputStream(), true);
fromServer = new BufferedReader (new InputStreamReader
    (socket.getInputStream()), 8000);

The true at the end the printWriter constructor tells it to auto flush (lovely term) the buffer when you issue a println.

When you actually use the socket, use the following:

toServer.println (msg.trim());
resp = fromServer.readLine().trim();

I don't have to append the \n to the outgoing text myself, but this may be related to my specific situation (more on that below). The incoming data needs to have a \n at its end or readLine doesn't work. I assume there are ways you could read from the socket byte by byte, but also that the code would not be nearly so simple.

Unfortunately, the TCP server I'm communicating with is a C++ program so the way we ensure the \n is present in the incoming data isn't going to work for you (And may not be needed in the outgoing data).

Finally, if it helps, I built my code based on this web example:

http://content.gpwiki.org/index.php/Java:Tutorials:Simple_TCP_Networking

Edit: I found another code example that uses DataOutputStream... You may find it helpful, assuming you haven't already seen it.

http://systembash.com/content/a-simple-java-tcp-server-and-tcp-client/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.