socket通信之多client,多线程

MultipleThreadServer端

package wbf.socket;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MultipleThreadServer {

	public static void main(String[] args) {
		ServerSocket server = null;
		Socket socket  = null;
		try {
			System.out.println("socket启动,等待客户端连接。。。");
			//启动server端,等待客户端连接
			server = new ServerSocket(9999);
			
			//启用线程池,不可以直接new Thread()来开启新线程,线程资源回收效率很低
			ExecutorService executorService = Executors.newFixedThreadPool(10);
			while (true) {
				socket = server.accept();
				executorService.submit(new SocketThread(socket));
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (socket != null) {
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (server != null) {
				try {
					server.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

class SocketThread implements Runnable {
	private Socket socket = null;
	public SocketThread() {
		super();
	}
	
	public SocketThread(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		InputStream input = null;
		OutputStream output = null;
		try {
			//接收client端发送的消息
			input = socket.getInputStream();
			byte[] bytes = new byte[1024];
			int len;
			StringBuilder builder = new StringBuilder();
			while ((len = input.read(bytes)) != -1) {
				builder.append(new String(bytes, 0, len, "UTF-8"));
			}
			System.out.println(builder);
			
			//接收到client消息后,作出回复
			//当前状态下,OutputStream需要关闭,否则client端接收消息时无法知道server的回复消息是否已经结束,会死循环等待
			output = socket.getOutputStream();
			output.write("你好client,我是server".getBytes("UTF-8"));
			
			//因为这段代码在死循环,所以必须手动关闭socket的OutputStream输出流,否则客户端无法判断服务器端的反馈信息是否输出完毕。
			socket.shutdownOutput();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (output != null) {
				try {
					output.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (input != null) {
				try {
					input.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
} 

Client端

package wbf.socket;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.TimeUnit;

public class Client {
	public static void main(String[] args) {
		Socket socket = null;
		OutputStream output = null;
		InputStream input = null;
		try {
			//连接server端,并通过OutputStream想server端发送第一条消息
			socket = new Socket("localhost", 9999);
			System.out.println("client连接成功。");
			output = socket.getOutputStream();
			output.write(("你好server,我是client" + System.currentTimeMillis()).getBytes("UTF-8"));
			
			//通过该方法,告诉server端消息已经发送完毕,server端就停止接收消息
			socket.shutdownOutput();
			
			//client端发送完消息后,启动InputStream等待接收server端的消息
			input = socket.getInputStream();
			byte[] bytes = new byte[1024];
			int len;
			StringBuilder builder = new StringBuilder();
			while ((len = input.read(bytes)) != -1) {
				builder.append(new String(bytes, 0, len, "UTF-8"));
			}
			System.out.println(builder);
			
			//睡30秒,防止client立刻关闭
			try {
				TimeUnit.SECONDS.sleep(30);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (input != null) {
				try {
					input.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (output != null) {
				try {
					output.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (socket != null) {
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

猜你喜欢

转载自my.oschina.net/wangbaofeng/blog/1825059