大家好,我创建了一个带有线程池的服务器类,如下所示,它利用了workerRunnable类。我用此代码面临的问题是当我尝试同时从两个客户端向该服务器发送文件时,它给了我一个不规则的响应(从某种意义上说,第一个线程将一直运行到尽快发出下一个客户端请求)来自第二个客户端的请求暨,它停止了第一个客户端,并开始处理第二个请求,第二个响应发送到两个客户端套接字,而不是发送它们各自的响应)...请问谁能告诉我我要去哪里错误?????
package com.tel.snmp;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.IOException;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadPooledServer implements Runnable{
protected int serverPort = 4444;//hk
protected ServerSocket serverSocket = null;
protected boolean isStopped = false;
protected Thread runningThread= null;
public BlockingQueue q = new ArrayBlockingQueue(20);
public static int clientconnection = 0;
ThreadPoolExecutor threadpool = new ThreadPoolExecutor(4,10,20,TimeUnit.SECONDS,q);
public ThreadPooledServer(int port){
this.serverPort = port; // wrk2
}
public void run()
{
synchronized(this)
{
this.runningThread = Thread.currentThread();
}
openServerSocket();
while(! isStopped()){
Socket clientSocket = null;
try
{
//System.out.println("the value of client connection BEFORE is"+clientconnection);
clientSocket = this.serverSocket.accept();
clientconnection++;
System.out.println("the value of client connection is"+clientconnection);
} catch (IOException e)
{
if(isStopped())
{
System.out.println("Server Stopped.") ;
return;
}
throw new RuntimeException(
"Error accepting client connection", e);
}
this.threadpool.execute(new WorkerRunnable(clientSocket,"Thread pooled server"));
}
System.out.println("Server Stopped.") ;
}
private synchronized boolean isStopped() {
return this.isStopped;
}
public synchronized void stop(){
this.isStopped = true;
try {
this.serverSocket.close();
} catch (IOException e) {
throw new RuntimeException("Error closing server", e);
}
}
private void openServerSocket() {
try {
this.serverSocket = new ServerSocket(this.serverPort); //wrkr2
}
catch (IOException e) {
throw new RuntimeException("Cannot open port serverPort"+serverPort, e);
}
}
}
-----------------------------Worker Runnable class-----------------------------
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.tel.snmp;
/**
*
* @author harikrishnadv
*/
import com.tel.common.ProtocolSelector;
import java.io.*;
import java.net.*;
/*public class WorkerRunnable implements Runnable{
protected Socket clientSocket = null;
protected String serverText = null;
public WorkerRunnable(Socket clientSocket, String serverText) {
this.clientSocket = clientSocket;
this.serverText = serverText;
}
public void run() {
try {
InputStream input = clientSocket.getInputStream();
OutputStream output = clientSocket.getOutputStream();
long time = System.currentTimeMillis();
output.write(("HTTP/1.1 200 OK\n\nWorkerRunnable: " +
this.serverText + " - " +
time +
"").getBytes());
output.close();
input.close();
System.out.println("Request processed: " + time);
} catch (IOException e) {
//report exception somewhere.
e.printStackTrace();
}
}
}
*/
public class WorkerRunnable implements Runnable
{
FileInputStream fis;
FileOutputStream fos;
BufferedInputStream bis;
BufferedOutputStream bos;
String filename="clientfile";
String fname=null;
//Socket soc;
int flag=0;
int ch;
//static int count=0;// new
protected Socket clientSocket = null;
protected String serverText = null;
public WorkerRunnable(Socket clientSocket, String serverText) {
this.clientSocket = clientSocket;
this.serverText = serverText;
}
public synchronized void run() {
try {
receiveFile();
/*try{
this.wait();
}
catch(InterruptedException i)
{
}*/
if(flag==1)
{
System.out.println("**********************************************************************************************************************************");
sendFile();
}
closeAll();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/** Method to send the response file to the client */
public void sendFile() throws IOException {
// SENDING A FILE
//String sendfile=EMS.fileprocessname+EMS.clientcount+".xml";
String sendfile=EM.fileprocessname;//+EM.clientcount;
System.out.println("filename that has been sending to client is"+sendfile);
bos = new BufferedOutputStream(clientSocket.getOutputStream());
//fis = new FileInputStream("C://outputs.xml");
fis = new FileInputStream(sendfile);
while ((ch = fis.read()) != -1) {
bos.write(ch);
bos.flush();
}
bos.write(-1);
bos.flush();
System.out.println("File Sent to :: " + clientSocket);
fis.close();
}
/** Method to receive input file from client */
public void receiveFile() throws IOException {
// RECEIVING A FILE
fname="C://"+filename+ThreadPooledServer.clientconnection+".xml";
bis = new BufferedInputStream(clientSocket.getInputStream());
//fos = new FileOutputStream("C://client.xml");
fos = new FileOutputStream(fname);
while ((ch = bis.read()) != 255) {
fos.write(ch);
fos.flush();
}
System.out.println("File Received from :: " +clientSocket);
fos.close();
if(flag==0){
ProtocolSelector m=new ProtocolSelector();
//m.xmldecider("C://client.xml");
m.xmldecider(fname);
flag=1;
}
}
public void closeAll() throws IOException {
bis.close();
bos.close();
}
}
对于您的宝贵答复,我将不胜感激
最佳答案
您的clientconnection
字段是静态的,但随后可以从您的WorkerRunnable receiveFile()
方法访问。到receiveFile()
方法执行时,不能保证clientconnection
的值仍然正确-另一个客户端可能已经出现并对其进行了递增。
尝试更改您的WorkerRunnable
构造函数以将clientconnection
用作参数,例如
更改:
this.threadpool.execute(new WorkerRunnable(clientSocket,
"Thread pooled server"));
至:
this.threadpool.execute(new WorkerRunnable(clientSocket, clientconnection,
"Thread pooled server"));
将
clientconnection
字段添加到WorkerRunnable
,然后更改此行:fname="C://"+filename+ThreadPooledServer.clientconnection+".xml";
至:
fname="C://"+filename+clientconnection+".xml";
关于java - 当我收到第二个客户端请求时,由于正在暂停第一个线程,因此无法使用线程池处理多个客户端,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1636714/