简要介绍
本例子中主要有四个类,Server类主要是等待客户端连接,和读取客户端发来的数据,并可以通过键盘向客户端发送消息,ServerThread类是在Server中调用的,它是一个线程,主要是实现服务端从键盘读取数据的功能,这里为什么要新建一个线程来读数据,因为BufferedReader的readLine()方法读取数据时,在该方法成功返回之前,线程被阻塞,程序无法再执行下去,所以要想输入数据必须新开线程。同样在Client中从服务端的输入流读数据也是在一个新的线程中。最好将下面四个类放在一个包下。
1、Server类
<pre name="code" class="java">import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; public class Server { public static void main(String[] args) throws IOException{ ServerSocket ss = new ServerSocket(3000); // 该缓冲流用于从客户端读入数据 BufferedReader read = null; String str = null; while(true){ // 服务器收到客户端的Socket请求时,服务端也创建一个Socket,如何没有客户端请求,该方法一直处于阻塞状态 Socket s = ss.accept(); read = new BufferedReader(new InputStreamReader(s.getInputStream())); // 该线程用于从键盘读取数据,并将数据写入Socket的输出流中 new Thread(new ServerThread(s)).start(); while((str = read.readLine())!=null){ System.out.println(str); } } } }
<pre name="code" class="java">import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; /** *该线程用于从键盘读取数据,并将数据写入Socket的输出流中 * @author 王维 * */ public class ServerThread implements Runnable { Socket s; // 用于将数据写入Socket中的输出流 PrintStream ps; // 从键盘中读取输入的内容 BufferedReader reader; public ServerThread(Socket s){ this.s = s; reader = new BufferedReader(new InputStreamReader(System.in)); } @Override public void run() { String str = null; try { ps = new PrintStream(s.getOutputStream()); while((str = reader.readLine()) != null){ ps.println(str+" (from Server)"); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
3、Client类
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; public class Client { public static void main(String[] args) throws IOException{ // 创建本机连接,端口号3000 Socket socket = new Socket("127.0.0.1", 3000); // 该流用于读取服务器发来的数据 PrintStream ps = new PrintStream(socket.getOutputStream()); String str = null; // 该流用于读取键盘的输入内容 BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); // 该线程用于从服务器中读入数据 new Thread(new ClientThread(socket)).start(); // 从键盘中读取数据 while((str = reader.readLine()) != null){ ps.println(str+" (from Client)"); } reader.close(); socket.close(); } }
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; /** * 该线程用于从服务器中读入数据 * @author 王维 * */ public class ClientThread implements Runnable{ Socket s; BufferedReader read; public ClientThread(Socket s){ this.s = s; try { // 从服务器中读取内容 read = new BufferedReader(new InputStreamReader(s.getInputStream())); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void run() { String str = null; try { while((str = read.readLine()) != null){ System.out.println(str); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }