Server.java
package socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;/**
 * 聊天室服务端
 * @author 小明
 *
 */
public class Server {
 /**
 * 运行在服务端的ServerSocket主要有两个作用:
 * 1:向系统申请服务端口,客户端就是通过这个端口与服务端建立连接的。
 * 2:监听服务端口,一旦客户端与服务端建立连接,就会
 * 自动创建一个Socket,并通过该Socket与建立连接的
 * 客户端进行交互。
 * 
 */
 private ServerSocket server;

 public Server()
 {
 try{
 /**
 * 实例化ServerSocket的同时要指定向系统申请的服务端口。注意,该端口
 * 不能与当前系统其它应用程序申请的端口号一致,
 * 否则会抛出端口被占用的异常。
 */
 System.out.println("正在启动服务端...");
 server = new ServerSocket(8088);
 System.out.println("服务端启动完毕!");
 }catch(Exception e){

 }
 }

 public void start()
 {
 try {
 while(true)
 {
 System.out.println("等待客户端连接");
 Socket socket = server.accept();
 //accept用来感知socket。
 System.out.println("一个客户端连接进去了。");

 ClientHandler hander = new ClientHandler(socket);
 Thread t1 = new Thread(hander);
 t1.start();
 }
 /**
 * 准备接受客户端连接
 * 
 * 这是一个阻塞方法。
 *一旦调用accpet()方法,服务端阻塞在这里,等着客户端连接了。
 *这时当我们启动客户端时,客户端实例化socket,通过IP找到应用程序。
 *这时accpet()马上就会有反应。accpet()方法执行完就返回一个socket。
 *通过这个socket就可以与刚建立连接的这个客户端进行通讯了。
 *客户端创建一个socket,服务端通过accept()接收一个socket。
 *这时候就可以进行沟通了。
 * 需要处理异常。
 */
 } catch (IOException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 }

 public static void main(String[] args) {
 Server server = new Server();
 server.start();
 } /**
 * 通过输入流读取远端计算机发送过来的信息时
 * br.readLine()方法对于不同系统的客户端断开时的反应不一样
 * windows的客户端断开时,会直接抛出异常
 * linux的客户端断开时,会返回null
 * 该线程任务是负责与指定的客户端进行交互
 * @author 小明
 *
 */
 private class ClientHandler implements Runnable{
 private Socket socket;
 private String host;
 //创建时需要将Socket传入,以便对该客户端交互
 public ClientHandler(Socket socket) {
 this.socket = socket;
 //通过socket获取远端的地址信息
 InetAddress address = socket.getInetAddress();
 host = address.getHostAddress();
 }
 @Override
 public void run() {
 try{
 System.out.println("进入了线程,现在正在调用run()方法");
 InputStream in = socket.getInputStream();
 InputStreamReader isr = new InputStreamReader(in);
 BufferedReader br = new BufferedReader(isr);
 String message = null;
 System.out.println("客户端地址是:" + host);
 //System.out.println("尝试输出br.readLine()" + br.readLine());
 System.out.println("while最上面的那条语句");

 while((message = br.readLine()) != null)
 {
 System.out.println("读取到了数据");
 System.out.println(host + "说" + message);
 System.out.println("一个客户端连接了");
 }
 if(message == null){
 System.out.println("message是空的");
 }
 br.close();
 }catch(IOException e){
 e.printStackTrace();
 }finally{
 //br.close();
 }
 }

 }

} 
Client.java
package socket;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;/**
 * 聊天室客户端
 * @author 小明
 *
 */
public class Client {
 /**
 * 套接字
 * 封装了TCP协议的通信细节,让我们可以简单地使用它完成TCP通讯
 * Socket连接后提供了两条流,通过两条流的读写操作完成与远端计算机的数据连接
 * 完成与远端计算机的数据交换。
 */
 private Socket socket;
 public Scanner reader;
 /**
 * 用来初始化客户端
 */
 public Client()
 {
 try {
 /**
 * 实例化Socket时需要传入两个参数:
 * 1:服务端的IP地址
 * 2:服务端的端口号
 * 通过IP地址可以找到服务端所在的计算机
 * 通过端口可以找到运行在服务端计算机上的
 * 服务端应用程序
 * 注意,实例化Socket的过程就是连接的过程,若
 * 连接失败就会抛出异常。
 */
 reader = new Scanner(System.in);

 System.out.println("正在连接服务端...");
 socket = new Socket("localhost", 8088);
 System.out.println("与服务端建立连接!");

 /**
 * 有两个参数,一个是IP地址,一个是端口号
 */
 /**
 * 所有应用程序在使用网络的时候都要和操作系统申请一个网络端口
 * 
 */
 /**
 * 异常要我们自己进行处理,不要抛出
 */
 }catch (IOException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }

 }

 /**
 * 写程序时不要过度依赖main方法
 * 客户端开始工作的方法
 */
 public void start()
 {
 try{
 //socket.getOutputStream();
 //打桩
 //可以找到代码错的地方。
 PrintWriter pw = new PrintWriter(
 new BufferedWriter(
 new OutputStreamWriter(
 socket.getOutputStream())), true);
 //pw.write("你好服务端");
 //使用上面这条语句是错的,要使用具有自动行刷新的方法
 //不要再下意识地写上面那条语句了
// for(int i = 0; i < 10; i++){
// pw.println("你好服务端!" + i);
// }
 while(true)
 {
 String line = reader.nextLine();
 pw.println(line);
 }

 }catch(Exception e){
 e.printStackTrace();
 }
 }
 public static void main(String[] args) {
 Client client = new Client();
 client.start();
 }

}