Hej arne
Programmet skal være en del af et større projekt, hvor det skal udvikles i java 1.4 (ved ikke om det måske kan have indflydelse på problemet), så jeg kan ikke bruge dit forslag med BlockingQue -> jeg vil dog gemme det til en anden gang :)
Jeg har prøver at simplificere koden og har her klippet det essentielle sammen, men stadig med samme funktionalitet. Programmet består her af 2 filer: den første er den del der lytter efter HTTP requests og den anden er et program, som tester det første. Når jeg kører det andet program, så er det, at jeg får de omtalte NoSuchElementExceptions.
Hvis parametrene i LoadTest programmet ændres, så den ikke sender så meget, så opstår fejlen ikke.
/Brian
Her er koden:
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class HTTPTest {
private int port = -1;
private int maxHandlerThreads = -1;
private int connectionQueueSize = -1;
private WorkerThread worker = null;
public static void main(String[] args) {
int port = 9876;
int maxHandlerThreads = 15;
int connectionQueueSize = 100;
new HTTPTest(port, maxHandlerThreads, connectionQueueSize).start();
}
public HTTPTest(int port, int maxHandlerThreads, int connectionQueueSize) {
this.port = port;
this.maxHandlerThreads = maxHandlerThreads;
this.connectionQueueSize = connectionQueueSize;
}
public void start() {
worker = new WorkerThread(port, maxHandlerThreads, connectionQueueSize);
worker.start();
}
public void stop() {
worker.terminate();
}
public class WorkerThread extends Thread {
private boolean running = true;
private int connectionQueSize;
private ServerSocket serverSocket = null;
private Socket socket = null;
private LinkedList socketQueue = new LinkedList();
private List handlerThreads = new ArrayList();
public WorkerThread(int port, int maxHandlerThreads,
int connectionQueueSize) {
// Open server socket
try {
this.serverSocket = new ServerSocket(port);
this.connectionQueSize = connectionQueueSize;
} catch (IOException e) {
throw new RuntimeException("Couldn't initialize server socket on port: " + port);
}
// Create handlerthreads
for (int i = 0; i < maxHandlerThreads; i++) {
final HandlerThread thread = new HandlerThread(socketQueue);
thread.start();
handlerThreads.add(thread);
}
}
public void run() {
while (running) {
socket = null;
try {
socket = this.serverSocket.accept();
} catch (IOException e) {
System.out.println(e);
}
// pass incoming connection to a handlerthread via the queue
synchronized (socketQueue) {
if (socketQueue.size() >= connectionQueSize) {
try {
socket.close();
} catch (IOException e) {
System.out.println(e);;
}
} else {
// add socket to queue for rocessing
socketQueue.add(socket);
socketQueue.notify();
}
}
}
}
public void terminate() {
try {
// terminate all handlerthreads
for (Iterator threads = socketQueue.iterator(); threads.hasNext();) {
((HandlerThread) threads.next()).terminate();
}
this.serverSocket.close();
} catch (IOException e) {
} // Ignored
running = false;
}
}
public class HandlerThread extends Thread {
private boolean running = true;
private LinkedList socketQueue = null;
private Socket socket;
public HandlerThread(LinkedList socketQueue) {
this.socketQueue = socketQueue;
}
public void run() {
while (running) {
socket = null;
// get a socket from the queue
synchronized (socketQueue) {
try {
if (socketQueue.isEmpty())
socketQueue.wait();
} catch (InterruptedException e) { /* ignored */
}
}
try {
socket = (Socket) socketQueue.removeFirst();
InputStream is = socket.getInputStream();
// wait up to 10.000 ms to recieve HTTP GET data
for (int waitCounter = 0; (waitCounter < 100)
&& (is.available() == 0); waitCounter++) {
Thread.sleep(100);
}
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
while (is.available() > 0) {
int data = is.read();
baos.write(data);
}
String response = null;
if (canHandle(baos.toString())) {
// send response '202 accepted' to HTTP agent
response = getResponse(202, "Request accepted");
} else {
// send response '405 not allowed' to HTTP agent
response = getResponse(405, "Request not allowed");
}
synchronized (socket) {
socket.getOutputStream().write(response.getBytes());
socket.getOutputStream().flush();
socket.close();
}
} catch (InterruptedException e) {
// ignored
} catch (IOException e) {
System.out.println(e);;
} catch (NoSuchElementException e) {
System.out.println("NoSuchElementException");
}
synchronized (this) {
try {
this.wait(10);
} catch (InterruptedException e) {/* Ignored */
}
}
}
}
public void terminate() {
running = false;
synchronized (socket) {
try {
if (socket != null) {
socket.getOutputStream().flush();
socket.close();
}
} catch (IOException e) {
System.out.println(e);
}
}
}
public boolean isRunning() {
return running;
}
public String getResponse(int code, String title) {
String response = "HTTP/1.1 " + code + " " + title + "\r\n"
+ "Date: " + new Date() + "\r\n"
+ "Content-Type: text/html\r\n\r\n"
+ "<!DOCTYPE html PUBLIC\"-//W3C//DTD HTML 4.01 TRANSITIONAL//EN\" "
+ "\"
http://www.w3.org/TR/html4/loose.dtd\">\r\n"+ "<HTML>\r\n" + "<HEAD>\r\n" + "<TITLE>" + code + " "
+ title + "</TITLE>\r\n" + "</HEAD>\r\n" + "<BODY>\r\n"
+ "<H1>Status: " + title + "</H1>\r\n" + "</BODY>\r\n"
+ "</HTML>\r\n";
return response;
}
// Check if the request validates according to reg.exp.
private boolean canHandle(String request) {
String s = request.replaceAll("\r", "").split("\n")[0];
String requestString = "GET\\s(/\\w+)*/\\?(\\w+=[a-zA-Z_0-9-]+&){1,4}(\\w+=[a-zA-Z_0-9-]+)\\sHTTP/1.[01]";
Pattern httpPattern = Pattern.compile(requestString);
Matcher httpMatcher = httpPattern.matcher(request);
return httpMatcher.matches();
}
}
}
import java.net.*;
import java.io.*;
public class LoadTest {
public static void main(String[] args) {
new LoadTest();
}
public LoadTest() {
for (int i = 0; i < 50; i++) {
new Tester().start();
}
}
private class Tester extends Thread {
public void run() {
for (int i = 0; i < 10; i++) {
sendGetRequest("
http://localhost:9876/", requestParameters());
try {
Thread.sleep(10);
} catch (InterruptedException e) {/* ignored */
}
}
}
private String requestParameters() {
String request = "";
request += "id=" + random(15);
return request;
}
private String random(int cifre) {
String tmp = "";
while (cifre > 0) {
tmp += (int) (Math.random() * 10);
cifre--;
}
return tmp;
}
public String sendGetRequest(String endpoint, String requestParameters) {
String result = null;
if (endpoint.startsWith("
http://")) {
// Send a GET request to the servlet
try {
// Construct data
StringBuffer data = new StringBuffer();
// Send data
String urlStr = endpoint;
if (requestParameters != null && requestParameters.length() > 0){
urlStr += "?" + requestParameters;
}
URL url = new URL(urlStr);
URLConnection conn = url.openConnection();
// Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuffer sb = new StringBuffer();
String line;
while ((line = rd.readLine()) != null) {
sb.append(line);
}
rd.close();
result = sb.toString();
} catch (Exception e) {
// e.printStackTrace();
}
}
return result;
}
}
}