我正在尝试将文本文件从客户端发送到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();
}
}
}
}
请查看并告诉我这种方法可能出现的问题?
答案 0 :(得分:0)
不要继续重新创建服务器套接字。将其初始化移至循环之前。您冒着绑定异常和客户连接拒绝的风险。
同样,您不应该在循环中创建ior关闭执行程序服务。