服务器套接字读取文件:无法处理来自BlockingQueue的记录

时间:2016-03-22 20:39:10

标签: java multithreading sockets blockingqueue

我正在尝试将文本文件从客户端发送到Socket Server。在顺序操作中使用单个线程读取文本文件。我正在使用BlockingQueue从读取操作放置记录并尝试使用多线程机制处理记录。如果没有套接字通信(即直接读取文件),此代码可以正常工作。

客户代码:

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

服务器代码:

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

请查看并告诉我这种方法可能出现的问题?

1 个答案:

答案 0 :(得分:0)

  • 不要继续重新创建服务器套接字。将其初始化移至循环之前。您冒着绑定异常和客户连接拒绝的风险。

  • 同样,您不应该在循环中创建ior关闭执行程序服务。