0

I am trying to send a text file from a client to Socket Server. The text file is read using a single thread in sequential operation. I am using BlockingQueue to place the records from read operation and trying to process the records using multi-thread mechanism. This code works perfectly fine if there is no socket communication (i.e. reading file directly).

Client Code:

        try{
            Socket socket = new Socket(hostName, PORTNUMBER);
            File file = new File(filePath);

            byte[] bytes = new byte[16 * 1024];
            InputStream in = new FileInputStream(file);
            OutputStream out = socket.getOutputStream();

            int count;
            while ((count = in.read(bytes)) > 0) {
                out.write(bytes, 0, count);
            }

            out.close();
            in.close();
            socket.close();
        }catch(UnknownHostException e){
            e.printStackTrace();
        }catch(IOException e){
            e.printStackTrace();
        }

Server Code:

public static final Map<Integer, Account> _resultMap= new ConcurrentHashMap<Integer, Account>();

public static void main(String[] args) throws IOException, InterruptedException, ExecutionException {
    while(true){
            if(mode.equals("deamon")){
                ServerSocket serverSocket = null;

                try {
                    serverSocket = new ServerSocket(8888);
                } catch (IOException ex) {
                    System.out.println("Unable to start up server on port 8888");
                }

               Socket socket = null;

                try {
                    socket = serverSocket.accept();
                } catch (IOException ex) {
                    System.out.println("Unable to accept client connection");
                }


                final int threadCount = 8;
                final BlockingQueue<String> queue = new LinkedBlockingQueue<String>(200);


                ExecutorService service = Executors.newFixedThreadPool(threadCount);
                for (int i = 0; i < (threadCount - 1); i++) {
                    service.submit(new CalcTask(queue));
                }
                service.submit(new ReadFileTask(queue, socket)).get();
                System.out.println(queue.size()); // Can see the count here

                service.shutdownNow();
                service.awaitTermination(365, TimeUnit.DAYS);


                for (Map.Entry<Integer, String> e : Map.entrySet()) {
                    System.out.println(e.getKey());
                }

                socket.close();
                serverSocket.close();
            }
    }

CalcTask:

Class CalcTask implements Runnable {
private final BlockingQueue<String> queue;

public CalcTask(BlockingQueue<String> queue) {
    this.queue = queue;
}

@Override
public void run() {
    String line;

    while (true) {
        try {
            //Queue is empty - so this block is not executing.
            line = queue.take();
            procesThis(line);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
            break;
        }
    }
    while ((line = queue.poll()) != null) {
        procesThis(line);
    }
}
}

ReadFileTask:

class ReadFileTask implements Runnable {
private final BlockingQueue<String> queue;
private Socket socket;


public ReadFileTask(BlockingQueue<String> queue, Socket socket) {
    this.queue = queue;
    this.socket = socket;
}

@Override
public void run() {
    BufferedReader br = null;
    try {
        br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        for (String line; (line = br.readLine()) != null; ) {
            queue.put(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        try {
            if (br != null) br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
}

Please review and let me know what could be wrong with this approach?

rslack
  • 61
  • 1
  • 5

1 Answers1

0
  • Don't keep re-creating the server socket. Move its initialization ahead of the loop. Your way you risk bind exceptions and client connnection refusals.

  • Similarly you shouldn't create ior shutdown the executor service inside the loop.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Thanks, I have moved the initialization to the top as you have suggested. And for the moment I have removed the loop as well (so only one client connection and terminate). But I find the shared BlockingQueue empty the moment 'CalcTask' thread is executed. Any pointers on how I could debug this please? – rslack Mar 22 '16 at 22:21