Guest User

Untitled

a guest
Dec 11th, 2017
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.55 KB | None | 0 0
  1. package yaraki.androidwebserver;
  2.  
  3. import java.io.BufferedInputStream;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.io.PrintStream;
  7. import java.net.ServerSocket;
  8. import java.net.Socket;
  9. import java.util.ArrayList;
  10. import java.util.List;
  11.  
  12. /**
  13. * Web サーバー。
  14. * <pre><code>
  15. * WebServer server = new WebServer(8080);
  16. * server.start();
  17. * </code></pre>
  18. */
  19. public class WebServer implements Runnable {
  20.  
  21. /** End of Line */
  22. private static final byte[] EOL = { (byte) '\r', (byte) '\n' };
  23. /** ワーカースレッドの最大数 */
  24. private static final int MAX_WORKERS = 10;
  25. /** ソケットタイムアウトまでのミリ秒 */
  26. private static final int SOCKET_TIMEOUT = 5000;
  27.  
  28. /** 待機状態のワーカースレッドたち */
  29. private final List<Worker> mWorkers;
  30. /** 生成されたワーカースレッドの総数 */
  31. private int mTotalWorkers;
  32. /** ポート番号 */
  33. private final int mPort;
  34.  
  35. public WebServer(int port) {
  36. mPort = port;
  37. mWorkers = new ArrayList<Worker>();
  38. for (int i = 0; i < MAX_WORKERS; ++i) {
  39. Worker worker = new Worker();
  40. (new Thread(worker, "Server Worker #" + i)).start();
  41. mWorkers.add(worker);
  42. }
  43. mTotalWorkers = MAX_WORKERS;
  44. }
  45.  
  46. public void run() {
  47. try {
  48. ServerSocket serverSocket = new ServerSocket(mPort);
  49. while (true) {
  50. Socket socket = serverSocket.accept();
  51. synchronized (mWorkers) {
  52. if (mWorkers.isEmpty()) {
  53. Worker worker = new Worker();
  54. worker.setSocket(socket);
  55. (new Thread(worker, "Server Worker #" + mTotalWorkers)).start();
  56. ++mTotalWorkers;
  57. } else {
  58. Worker worker = mWorkers.get(0);
  59. mWorkers.remove(0);
  60. worker.setSocket(socket);
  61. }
  62. }
  63. }
  64. } catch (IOException e) {
  65. e.printStackTrace();
  66. }
  67. }
  68.  
  69. public void start() {
  70. new Thread(this).start();
  71. }
  72.  
  73. /**
  74. * 再利用可能なワーカースレッドを復帰させる。必要ない場合は破棄する。
  75. * @param worker 再利用可能なワーカースレッド
  76. */
  77. private void reuseWorker(Worker worker) {
  78. synchronized (mWorkers) {
  79. if (mWorkers.size() < MAX_WORKERS) {
  80. mWorkers.add(worker);
  81. } else {
  82. worker.abandone();
  83. }
  84. }
  85. }
  86.  
  87. private class Worker implements Runnable {
  88.  
  89. private Socket mSocket = null;
  90. private boolean mIsAlive = true;
  91.  
  92. @Override
  93. public synchronized void run() {
  94. while (mIsAlive) {
  95. // ソケットが結びつけられるまで待つ
  96. if (null == mSocket) {
  97. try {
  98. wait();
  99. } catch (InterruptedException e) { // 起こらないはず
  100. continue;
  101. }
  102. }
  103. // クライアントの相手をする
  104. try {
  105. handleClient();
  106. mSocket.close();
  107. } catch (IOException e) {
  108. e.printStackTrace();
  109. }
  110. // おしまい
  111. mSocket = null;
  112. reuseWorker(this);
  113. }
  114. }
  115.  
  116. public synchronized void setSocket(Socket socket) {
  117. mSocket = socket;
  118. notify();
  119. }
  120.  
  121. public void abandone() {
  122. mIsAlive = false;
  123. }
  124.  
  125. private void handleClient() throws IOException {
  126. InputStream in = new BufferedInputStream(mSocket.getInputStream(), 1024);
  127. byte[] buffer = new byte[1024];
  128. in.read(buffer);
  129. PrintStream out = new PrintStream(mSocket.getOutputStream());
  130. mSocket.setSoTimeout(SOCKET_TIMEOUT);
  131. out.print("HTTP/1.0 200 OK");
  132. out.write(EOL);
  133. out.print("Content-Type: text/html");
  134. out.write(EOL);
  135. out.write(EOL);
  136. out.print("Hello, world!");
  137. out.write(EOL);
  138. out.flush();
  139. out.close();
  140. in.close();
  141. }
  142. }
  143. }
Add Comment
Please, Sign In to add comment