Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package yaraki.androidwebserver;
- import java.io.BufferedInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.PrintStream;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.util.ArrayList;
- import java.util.List;
- /**
- * Web サーバー。
- * <pre><code>
- * WebServer server = new WebServer(8080);
- * server.start();
- * </code></pre>
- */
- public class WebServer implements Runnable {
- /** End of Line */
- private static final byte[] EOL = { (byte) '\r', (byte) '\n' };
- /** ワーカースレッドの最大数 */
- private static final int MAX_WORKERS = 10;
- /** ソケットタイムアウトまでのミリ秒 */
- private static final int SOCKET_TIMEOUT = 5000;
- /** 待機状態のワーカースレッドたち */
- private final List<Worker> mWorkers;
- /** 生成されたワーカースレッドの総数 */
- private int mTotalWorkers;
- /** ポート番号 */
- private final int mPort;
- public WebServer(int port) {
- mPort = port;
- mWorkers = new ArrayList<Worker>();
- for (int i = 0; i < MAX_WORKERS; ++i) {
- Worker worker = new Worker();
- (new Thread(worker, "Server Worker #" + i)).start();
- mWorkers.add(worker);
- }
- mTotalWorkers = MAX_WORKERS;
- }
- public void run() {
- try {
- ServerSocket serverSocket = new ServerSocket(mPort);
- while (true) {
- Socket socket = serverSocket.accept();
- synchronized (mWorkers) {
- if (mWorkers.isEmpty()) {
- Worker worker = new Worker();
- worker.setSocket(socket);
- (new Thread(worker, "Server Worker #" + mTotalWorkers)).start();
- ++mTotalWorkers;
- } else {
- Worker worker = mWorkers.get(0);
- mWorkers.remove(0);
- worker.setSocket(socket);
- }
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- public void start() {
- new Thread(this).start();
- }
- /**
- * 再利用可能なワーカースレッドを復帰させる。必要ない場合は破棄する。
- * @param worker 再利用可能なワーカースレッド
- */
- private void reuseWorker(Worker worker) {
- synchronized (mWorkers) {
- if (mWorkers.size() < MAX_WORKERS) {
- mWorkers.add(worker);
- } else {
- worker.abandone();
- }
- }
- }
- private class Worker implements Runnable {
- private Socket mSocket = null;
- private boolean mIsAlive = true;
- @Override
- public synchronized void run() {
- while (mIsAlive) {
- // ソケットが結びつけられるまで待つ
- if (null == mSocket) {
- try {
- wait();
- } catch (InterruptedException e) { // 起こらないはず
- continue;
- }
- }
- // クライアントの相手をする
- try {
- handleClient();
- mSocket.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- // おしまい
- mSocket = null;
- reuseWorker(this);
- }
- }
- public synchronized void setSocket(Socket socket) {
- mSocket = socket;
- notify();
- }
- public void abandone() {
- mIsAlive = false;
- }
- private void handleClient() throws IOException {
- InputStream in = new BufferedInputStream(mSocket.getInputStream(), 1024);
- byte[] buffer = new byte[1024];
- in.read(buffer);
- PrintStream out = new PrintStream(mSocket.getOutputStream());
- mSocket.setSoTimeout(SOCKET_TIMEOUT);
- out.print("HTTP/1.0 200 OK");
- out.write(EOL);
- out.print("Content-Type: text/html");
- out.write(EOL);
- out.write(EOL);
- out.print("Hello, world!");
- out.write(EOL);
- out.flush();
- out.close();
- in.close();
- }
- }
- }
Add Comment
Please, Sign In to add comment