Jump to content

Program hangs after thread finishes working

- - - - -

  • Please log in to reply
8 replies to this topic

#1
thatsme

thatsme

    Programmer

  • Members
  • PipPipPipPip
  • 176 posts
Hi. I try to program my first socket application, but some problems occur. There you see the most important method of menu entermenu(). this method calls registerNewBook() method which connects to server which is class BookStoreServer and sends data trough socket . Then the thread in the server is created and it succesffuly inserts data into srever. However after thread finishes work the program hangs and done1 is not printed after registerNewBook() method has finished. why this happends? some help would be appreciated

    public static  void enterMenu(){
        boolean exitFlag = false;
        
        while (!exitFlag){
            printMenu();
            int val = inputInteger();
            if (val != 0){
                switch (val){
                    case 1:
                        registerNewBook();
                        System.out.println("done1");
                        break;
                    case 2:
                        getBookData();
                        System.out.println("done2");
                        break;
                    case 3:
                        System.out.println("Finishing work");
                        exitFlag = true;
                        break;
                    default:
                        System.out.println("Nëra tokio pasirinkimo");
                        break;
                }
            }
        }
    }

    private static void registerNewBook(){
        System.out.println("Áveskite knygos pavadinimà");
        String title = inputString();
        
        System.out.println("Áveskite knygos autoriø");
        String author = inputString();
        
        System.out.println("Áveskite knygos iðleidimo metus");
        String publishingYear = inputString();
        
        try{
            Socket newClientSocket = new Socket("localhost", PORT);
            ObjectOutputStream out = new ObjectOutputStream(newClientSocket.getOutputStream());
            Book book = new Book(title, author, publishingYear);
            Package userPackage = new Package("bookRegistration");
            Object[] objectsToSend = new Object[1];
            objectsToSend[0] = book;
            userPackage.setObjects(objectsToSend);
            out.writeObject(userPackage);
            out.flush();
            out.close();
            newClientSocket.close();
        } catch (UnknownHostException e) {
            System.out.println("Host was not found");
            System.exit(1);
        } catch (IOException e) {
            System.out.println("Error while sending objects to server");
            System.exit(1);
        }
    } 

public class BookStoreServer{
    
    static final int PORT = 20000; 
    static final int MAX_QUEUE_LENGTH = 5;
    
    static BooksList booksList = new BooksList();
    
    public static void main(String args[]) throws UnknownHostException{    
        
        ServerSocket serverSocket = null;
        
        Socket clientSocket = null;
        try{
            serverSocket = new ServerSocket(PORT);
            serverSocket.setReuseAddress(true);
            System.out.println("Successfully conected. Server is running");
            while (true){
                clientSocket = serverSocket.accept();
                new ConnectionHandler(clientSocket);
            }
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
            System.out.println("Server shut down");
        }
    }
        
    static class ConnectionHandler implements Runnable{
        ObjectOutputStream out;
        ObjectInputStream in;
        Socket clientSocket;
        
        public ConnectionHandler(Socket clientSocket){
            this.clientSocket = clientSocket;
            System.out.println("Client connected successfully");
            (new Thread(this)).start();
        }
        
        void registerBook(Book book){
            booksList.insertBook(book);
            try {
                out.close();
            } catch (IOException e) {
                System.out.println("Error");
                System.exit(1);
            }
        }
        
        public void run(){
            try {
                System.out.println("Execution of query started");
                out = new ObjectOutputStream(clientSocket.getOutputStream());
                in = new ObjectInputStream(clientSocket.getInputStream());
                
                Package userPackage = (Package) in.readObject();
                String packageType = userPackage.getType();
                if (packageType.equals("bookRegistration")){
                    Object[] receivedObjects = userPackage.getObjects();
                    Book book = (Book) receivedObjects[0];
                    registerBook(book);
                    System.out.println("Now there are " + booksList.getBooksCount() + " books in the bookstore");
                }
            } catch (IOException e) {
                System.out.println("Failed to get I/O");
                e.printStackTrace();
                System.exit(1);
            } catch (ClassNotFoundException e){
                System.out.println("Class not found");
                System.exit(1);
            } finally {
                try {
                    clientSocket.close();
                    out.close();
                    in.close();
                    System.out.println("Execution of query finished successfully");
                }
                    catch (IOException e) {
                        System.out.println("Error");
                        System.exit(1);
                }
            }
        }
    }
}    


#2
wim DC

wim DC

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,084 posts
  • Programming Language:Java, JavaScript, PL/SQL
  • Learning:Java
Could you tell which output you get? (The println's you see)
(At the server side)

#3
thatsme

thatsme

    Programmer

  • Members
  • PipPipPipPip
  • 176 posts
I get the following output:

Successfully conected. Server is running
Client connected successfully
Now there are 1 books in the bookstore");
Execution of query started

Morover, i added this code to run() after the call registerBook() method
                    Package serverPackage = new Package("message");
                    Object[] objects = new Object[1] ;
                    objects[0] = "Now there are " + booksList.getBooksCount() + " books in the bookstore";
                    serverPackage.setObjects(objects);
                    out.writeObject(serverPackage);
                    out.flush(); 
and this code produces such exception:
java.net.SocketException: Socket closed
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at java.io.ObjectOutputStream$BlockDataOutputStream.drain(Unknown Source)
at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(Unknown Source)
at java.io.ObjectOutputStream.writeNonProxyDesc(Unknown Source)
at java.io.ObjectOutputStream.writeClassDesc(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeFatalException(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at BookStoreServer$ConnectionHandler.run(BookStoreServer.java:78)
at java.lang.Thread.run(Unknown Source)

#4
WingedPanther

WingedPanther

    A spammer's worst nightmare

  • Moderators
  • 16,831 posts
  • Location:Upstate, South Carolina
  • Programming Language:C, C++, PL/SQL, Delphi/Object Pascal, Pascal, Transact-SQL, Others
  • Learning:Java, C#, PHP, JavaScript, Lisp, Fortran, Haskell, Others
It's not clear where you put this code, but it looks like after you've called out.close().
Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

#5
lethalwire

lethalwire

    while(false){ ... }

  • Members
  • PipPipPipPipPipPipPip
  • 748 posts
  • Programming Language:Java, PHP
  • Learning:Java, PHP
You could be trying to do something with a socket after it is closed. It could be reading/writing/closing a socket even though it's closed.

#6
wim DC

wim DC

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,084 posts
  • Programming Language:Java, JavaScript, PL/SQL
  • Learning:Java

thatsme said:

I get the following output:

Successfully conected. Server is running
Client connected successfully
Now there are 1 books in the bookstore");
Execution of query started

Morover, i added this code to run() after the call registerBook() method
                    Package serverPackage = new Package("message");

                    Object[] objects = new Object[1] ;

                    objects[0] = "Now there are " + booksList.getBooksCount() + " books in the bookstore";

                    serverPackage.setObjects(objects);

                    out.writeObject(serverPackage);

                    out.flush(); 
and this code produces such exception:
java.net.SocketException: Socket closed
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at java.io.ObjectOutputStream$BlockDataOutputStream.drain(Unknown Source)
at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(Unknown Source)
at java.io.ObjectOutputStream.writeNonProxyDesc(Unknown Source)
at java.io.ObjectOutputStream.writeClassDesc(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeFatalException(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at BookStoreServer$ConnectionHandler.run(BookStoreServer.java:78)
at java.lang.Thread.run(Unknown Source)
That part is normal, cause you close the "out" in registerbook()
void registerBook(Book book){

            booksList.insertBook(book);

            try {

               [SIZE=4][B] out.close();[/B][/SIZE]

            } catch (IOException e) {

                System.out.println("Error");

                System.exit(1);

            }

        }
Still doesn't explain why it would not print
System.out.println("Now there are " + booksList.getBooksCount() + " books in the bookstore");

What happens inside
booksList.getBooksCount();
?

#7
thatsme

thatsme

    Programmer

  • Members
  • PipPipPipPip
  • 176 posts
I was advised by friend to modify my code, but I still get exception in bolded line in run() method :
java.net.SocketException: socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.io.ObjectInputStream$PeekInputStream.peek(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.peek(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at BookStoreServer$ConnectionHandler.run(BookStoreServer.java:69)
at java.lang.Thread.run(Unknown Source)

the output of program is:
Successfully conected. Server is running
Client connected successfully
Execution of query started
Now there are 1 books in the bookstore
Failed to get I/O

The modified code:
Menu.java
private static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    private static final int PORT = 20002;
    private static Socket newClientSocket;
    private static ObjectOutputStream out;
    private static ObjectInputStream in;
    
    public static  void enterMenu(){
        boolean exitFlag = false;
        try{
            newClientSocket = new Socket("localhost", PORT);
            out = new ObjectOutputStream(newClientSocket.getOutputStream());
            in = new ObjectInputStream(newClientSocket.getInputStream());
            
            while (!exitFlag){
                printMenu();
                int val = inputInteger();
                if (val != 0){
                    switch (val){
                        case 1:
                            registerNewBook();
                            System.out.println("done1");
                            break;
                        case 2:
                            getBookData();
                            System.out.println("done2");
                            break;
                        case 3:
                            System.out.println("Finishing work");
                            in.close();
                            out.close();
                            newClientSocket.close();
                            exitFlag = true;
                            break;
                        default:
                            System.out.println("Nėra tokio pasirinkimo");
                            break;
                    }
                }
            }
        } catch (UnknownHostException e) {
            System.out.println("Host was not found");
            System.exit(1);
        } catch (IOException e) {
            System.out.println("Error while sending objects to server");
            System.exit(1);
        }

    private static void registerNewBook(){
        //System.out.println("in method");
        System.out.println("Įveskite knygos pavadinimą");
        String title = inputString();
        
        System.out.println("Įveskite knygos autorių");
        String author = inputString();
        
        System.out.println("Įveskite knygos išleidimo metus");
        String publishingYear = inputString();
        
        try{
            Book book = new Book(title, author, publishingYear);
            Package userPackage = new Package("bookRegistration");
            Object[] objectsToSend = new Object[1];
            objectsToSend[0] = book;
            userPackage.setObjects(objectsToSend);
            out.writeObject(userPackage);
            out.flush();
        } catch (IOException e) {
            System.out.println("Error while sending objects to server");
            System.exit(1);
        } 
    }

BookStoreServer.java:
public class BookStoreServer{
    
    static final int PORT = 20002; 
    static final int MAX_QUEUE_LENGTH = 5;
    
    static BooksList booksList = new BooksList();
    
    public static void main(String args[]) throws UnknownHostException{    
        
        ServerSocket serverSocket = null;
        
        Socket clientSocket = null;
        try{
            serverSocket = new ServerSocket(PORT);
            serverSocket.setReuseAddress(true);
            System.out.println("Successfully conected. Server is running");
            while (true){
                clientSocket = serverSocket.accept();
                new ConnectionHandler(clientSocket);
            }
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
            System.out.println("Server shut down");
        }
    }
        
    static class ConnectionHandler implements Runnable{
        ObjectOutputStream out;
        ObjectInputStream in;
        Socket clientSocket;
        
        public ConnectionHandler(Socket clientSocket){
            this.clientSocket = clientSocket;
            System.out.println("Client connected successfully");
            (new Thread(this)).start();
        }
        
        void registerBook(Book book){
            booksList.insertBook(book);
            try {
                out.close();
            } catch (IOException e) {
                System.out.println("Error");
                System.exit(1);
            }
        }
        
        public void run(){
            try {
                System.out.println("Execution of query started");
                out = new ObjectOutputStream(clientSocket.getOutputStream());
                in = new ObjectInputStream(clientSocket.getInputStream());
                
                while (true){
                    [B]Package userPackage = (Package) in.readObject();[/B]
                    String packageType = userPackage.getType();
                    if (packageType.equals("bookRegistration")){
                        Object[] receivedObjects = userPackage.getObjects();
                        Book book = (Book) receivedObjects[0];
                        registerBook(book);
                        System.out.println("Now there are " + booksList.getBooksCount() + " books in the bookstore");
                    }
                }
            } catch (IOException e) {
                System.out.println("Failed to get I/O");
                e.printStackTrace();
                System.exit(1);
            } catch (ClassNotFoundException e){
                System.out.println("Class not found");
                System.exit(1);
            } finally {
                try {
                    clientSocket.close();
                    out.close();
                    in.close();
                    System.out.println("Execution of query finished successfully");
                }
                    catch (IOException e) {
                        System.out.println("Error");
                        System.exit(1);
                }
            }
        }
    }
}

Here is class BookList:
import java.util.HashMap;

public class BooksList{
    private HashMap<String, Book> booksList = new HashMap<String, Book>();
    
    public void insertBook(Book book){
        booksList.put(book.getTitle(), book);
    }
    
    public Book getBook(String title){
        return booksList.get(title);
    }
    
    public int getBooksCount(){
        return booksList.size();
    }
}


#8
lethalwire

lethalwire

    while(false){ ... }

  • Members
  • PipPipPipPipPipPipPip
  • 748 posts
  • Programming Language:Java, PHP
  • Learning:Java, PHP
Is the socket closing after you registerBook?
After 1 iteration of this:

while (true){

                    Package userPackage = (Package) in.readObject();

                    String packageType = userPackage.getType();

                    if (packageType.equals("bookRegistration")){

                        Object[] receivedObjects = userPackage.getObjects();

                        Book book = (Book) receivedObjects[0];

                        registerBook(book);

                        System.out.println("Now there are " + booksList.getBooksCount() + " books in the bookstore");

                    }

                }
It would seem as it would correctly insert a book due to:

        void registerBook(Book book){

            booksList.insertBook(book);

            try {

                out.close();

            } catch (IOException e) {

                System.out.println("Error");

                System.exit(1);

            }

        }
But you also call
out.close();
in this method.
So the next time through you iteration and you try to registerBook, is your socket already closed?

In other words, do you write an object to the socket, then close it, then try to write another object while the socket is closed?

#9
thatsme

thatsme

    Programmer

  • Members
  • PipPipPipPip
  • 176 posts
Thank's for help. It was silly mistake of closing socket in registerBook() method. sorry for late response




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users