Java 服务器套接字读取文件:无法处理BlockingQueue中的记录
我正在尝试将文本文件从客户端发送到套接字服务器。在顺序操作中使用单个线程读取文本文件。我正在使用BlockingQueue放置读取操作的记录,并尝试使用多线程机制处理这些记录。如果没有套接字通信(即,直接读取文件),则此代码可以很好地工作 客户端代码:Java 服务器套接字读取文件:无法处理BlockingQueue中的记录,java,multithreading,sockets,blockingqueue,Java,Multithreading,Sockets,Blockingqueue,我正在尝试将文本文件从客户端发送到套接字服务器。在顺序操作中使用单个线程读取文本文件。我正在使用BlockingQueue放置读取操作的记录,并尝试使用多线程机制处理这些记录。如果没有套接字通信(即,直接读取文件),则此代码可以很好地工作 客户端代码: try{ Socket socket = new Socket(hostName, PORTNUMBER); File file = new File(filePath);
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();
}
}
publicstaticfinalmap\u resultMap=newconcurrenthashmap();
公共静态void main(字符串[]args)引发IOException、InterruptedException、ExecutionException{
while(true){
if(模式等于(“deamon”)){
ServerSocket ServerSocket=null;
试一试{
serverSocket=新的serverSocket(8888);
}捕获(IOEX异常){
System.out.println(“无法在端口8888上启动服务器”);
}
套接字=空;
试一试{
socket=serverSocket.accept();
}捕获(IOEX异常){
System.out.println(“无法接受客户端连接”);
}
最终int螺纹数=8;
最终阻塞队列=新的LinkedBlockingQueue(200);
ExecutorService=Executors.newFixedThreadPool(线程计数);
对于(int i=0;i<(threadCount-1);i++){
提交(新的CalcTask(队列));
}
提交(新的ReadFileTask(队列,套接字)).get();
System.out.println(queue.size());//可以在这里看到计数
service.shutdownNow();
服务终止(365,时间单位:天);
对于(Map.Entry 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);
}
}
}
类CalcTask实现可运行{
私有最终阻塞队列;
公共CalcTask(阻塞队列){
this.queue=队列;
}
@凌驾
公开募捐{
弦线;
while(true){
试一试{
//队列为空-因此此块未执行。
line=queue.take();
procesThis(行);
}捕获(中断异常例外){
例如printStackTrace();
打破
}
}
而((line=queue.poll())!=null){
procesThis(行);
}
}
}
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();
}
}
}
}
class ReadFileTask实现可运行{
私有最终阻塞队列;
专用插座;
公共ReadFileTask(阻塞队列、套接字){
this.queue=队列;
this.socket=socket;
}
@凌驾
公开募捐{
BufferedReader br=null;
试一试{
br=新的BufferedReader(新的InputStreamReader(socket.getInputStream());
for(字符串行;(line=br.readLine())!=null;){
排队.放(线);
}
}捕获(IOE异常){
e、 printStackTrace();
}捕捉(中断异常e){
e、 printStackTrace();
}最后{
试一试{
如果(br!=null)br.close();
}捕获(IOE异常){
e、 printStackTrace();
}
}
}
}
请检查并让我知道这种方法可能有什么问题?- 不要继续重新创建服务器套接字。将其初始化移到循环之前。您的方式可能会导致绑定异常和客户端连接拒绝
- 同样,您不应该在循环内创建ior或关闭executor服务