多线程Java Socket编程示例
这篇做为学习孙卫琴<>的学习笔记吧.其中采用Java 5的ExecutorService来进行线程池的方式实现多线程,模拟客户端多用户向同一服务器端发送请求.
1.服务端
1. package sterning;
2.
3. import java.io.BufferedReader;
4. import java.io.IOException;
5. import java.io.InputStream;
6. import java.io.InputStreamReader;
7. import java.io.OutputStream;
8. import java.io.PrintWriter;
9. import java.net.*;
10. import java.util.concurrent.*;
11.
12. public class MultiThreadServer {
13. private int port=8821;
14. private ServerSocket serverSocket;
15. private ExecutorService executorService;//线程池
16. private final int POOL_SIZE=10;//单个CPU线程池大小
17.
18. public MultiThreadServer() throws IOException{
19. serverSocket=new ServerSocket(port);
20. //Runtime的availableProcessor()方法返回当前系统的CPU数目.
21. executorService=Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*POOL_SIZE);
22. System.out.println("服务器启动");
23. }
24.
25. public void service(){
26. while(true){
27. Socket socket=null;
28. try {
29. //接收客户连接,只要客户进行了连接,就会触发accept();从而建立连接
30. socket=serverSocket.accept();
31. executorService.execute(new Handler(socket));
32.
33. } catch (Exception e) {
34. e.printStackTrace();
35. }
36. }
37. }
38.
39. public static void main(String[] args) throws IOException {
40. new MultiThreadServer().service();
41. }
42.
43. }
44.
45. class Handler implements Runnable{
46. private Socket socket;
47. public Handler(Socket socket){
48. this.socket=socket;
49. }
50. private PrintWriter getWriter(Socket socket) throws IOException{
51. OutputStream socketOut=socket.getOutputStream();
52. return new PrintWriter(socketOut,true);
53. }
54. private BufferedReader getReader(Socket socket) throws IOException{
55. InputStream socketIn=socket.getInputStream();
56. return new BufferedReader(new InputStreamReader(socketIn));
57. }
58. public String echo(String msg){
59. return "echo:"+msg;
60. }
61. public void run(){
62. try {
63. System.out.println("New connection accepted "+socket.getInetAddress()+":"+socket.getPort());
64. BufferedReader br=getReader(socket);
65. PrintWriter pw=getWriter(socket);
66. String msg=null;
67. while((msg=br.readLine())!=null){
68. System.out.println(msg);
69. pw.println(echo(msg));
70. if(msg.equals("bye"))
71. break;
72. }
73. } catch (IOException e) {
74. e.printStackTrace();
75. }finally{
76. try {
77. if(socket!=null)
78. socket.close();
79. } catch (IOException e) {
80. e.printStackTrace();
81. }
82. }
83. }
84. }
2.客户端
1. package sterning;
2.
3. import java.io.BufferedReader;
4. import java.io.IOException;
5. import java.io.InputStreamReader;
6. import java.io.OutputStream;
7. import java.net.Socket;
8. import java.util.concurrent.ExecutorService;
9. import java.util.concurrent.Executors;
10.
11. public class MultiThreadClient {
12.
13. public static void main(String[] args) {
14. int numTasks = 10;
15.
16. ExecutorService exec = Executors.newCachedThreadPool();
17.
18. for (int i = 0; i < numTasks; i++) {
19. exec.execute(createTask(i));
20. }
21.
22. }
23.
24. // 定义一个简单的任务
25. private static Runnable createTask(final int taskID) {
26. return new Runnable() {
27. private Socket socket = null;
28. private int port=8821;
29.
30. public void run() {
31. System.out.println("Task " + taskID + ":start");
32. try {
33. socket = new Socket("localhost", port);
34. // 发送关闭命令
35. OutputStream socketOut = socket.getOutputStream();
36. socketOut.write("shutdown\r\n".getBytes());
37.
38. // 接收服务器的反馈
39. BufferedReader br = new BufferedReader(
40. new InputStreamReader(socket.getInputStream()));
41. String msg = null;
42. while ((msg = br.readLine()) != null)
43. System.out.println(msg);
44. } catch (IOException e) {
45. e.printStackTrace();
46. }
47. }
48.
49. };
50. }
51. }