首先写一个ServerSocket(服务器端的监听类)用于监听Socket连接,每新产生一个对话,都交由Socket的实例去处理.

package com.pan.socket.service;

import javax.net.ServerSocketFactory;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Created by pan on 2016/10/4.
 */
public class MyServer extends Thread {

    public void run() {
        try {
            //创建serverSocket,并绑定端口.
            ServerSocket serverSocket = ServerSocketFactory.getDefault().createServerSocket(2354);
            System.out.println("服务启动成功,正在监听端口2354");
            //接受客户端请求
            while (true) {
                Socket accept = serverSocket.accept();
                //每新增一个对话,交给一个Socket的实例去处理
                new MySocket(accept).start();
                System.out.println("客户端已经连接...");
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

然后,编写Socket服务端实例,用于与客户端的通信

package com.pan.socket.service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

/**
 * Created by pan on 2016/10/4.
 */
public class MySocket extends Thread {
    private Socket socket;

    //实例化传入socket对象
    public MySocket(Socket socket) {
        this.socket = socket;
    }


    public void run() {
        //像客户端输出提示信息
        write("已经连接..");
        //读取客户端的输入
        reader();
    }

    /**
     * 读取客户端输入的数据
     */
    private void reader() {
        try {
            //接受客户端数据
            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"), MAX_PRIORITY);
            String line;
            //循环读取客户端的数据
            while ((line = reader.readLine()) != null) {
                //退出指令
                if (!line.equalsIgnoreCase("exit")) {
                    System.out.println("客户端输入:" + line);
                    //向客户端写入
                    write(line);
                } else {
                    write("正在退出...");
                    System.out.println("一个客户端退出");
                    break;
                }
            }
            //关闭流
            reader.close();
        } catch (IOException e) {
            System.out.println("失去响应");
        }
    }

    /**
     * 向客户端写入数据
     */
    void write(String str) {
        try {
            socket.getOutputStream().write((str + "\n").getBytes("UTF-8"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

然后是启动服务端的类,用于启动服务.

package com.pan.socket.service;

/**
 * Created by pan on 2016/10/4.
 */
public class Main {

    public static void main(String[] args) {
        new MyServer().start();
    }

}

第二部分:客户端代码

客户端首先需要新建一个类,用于连接服务端.并接受服务端信息,以及向服务端发送消息.客户端不需要监听Socket,所以相比于服务端要少一个监听的类.

连接服务端并执行信息处理类

package com.pan.socket.client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.Scanner;

/**
 * Created by pan on 2016/10/4.
 */
public class ClientSocket extends Thread {
    private Socket socket;

    public void run() {
        try {
            socket = new Socket("127.0.0.1", 2354);
            new Thread() {
                public void run() {
                    //接受用户输入
                    Scanner scanner = new Scanner(System.in);
                    String inStr;
                    while ((inStr = scanner.nextLine()) != null) {
                        write(inStr);
                        //退出指令
                        if (inStr.equalsIgnoreCase("exit")) {
                            System.out.println("客户端退出");
                            break;
                        }
                    }
                    //输入流关闭
                    scanner.close();
                }
            }.start();
            //读取服务端消息
            reader();

        } catch (IOException e) {
            System.out.println("连接失败");
        }
    }

    /**
     * 读取服务端数据
     */
    private void reader() {
        try {
            //接受客户端数据
            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"), MAX_PRIORITY);
            String line;
            //循环读取服务端的数据
            while ((line = reader.readLine()) != null) {
                System.out.println("服务端:" + line);
            }
            //关闭流
            reader.close();
        } catch (IOException e) {
            System.out.println("失去响应");
        }
    }

    /**
     * 向服务端些数据
     */
    void write(String str) {
        try {
            socket.getOutputStream().write((str + "\n").getBytes("UTF-8"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}

ps:这里采用控制台输入,因为两个死循环,所以采用new Thread(){} ;新建一个线程去处理循环监听控制台输入,主线程循环监听服务端数据.

2.启动客户端类

package com.pan.socket.client;

/**
 * Created by pan on 2016/10/4.
 */
public class Main {

    public static void main(String[] args) {
        new ClientSocket().start();
    }
}

3.测试:

启动服务端,然后在启动客户端,输入一些数据.

4.结果

服务端:

服务启动成功,正在监听端口2354
客户端已经连接...
客户端输入:88
客户端输入:萨大幅
客户端输入:sa
一个客户端退出

客户端:

服务端:已经连接..
88
服务端:88
萨大幅
服务端:萨大幅
sa
服务端:sa
exit
客户端退出
服务端:正在退出...

Process finished with exit code 0

 

题外:

    如果需要通知功能,那么服务端添加一个用于管理MySocket的类,在该类下来实现MySocket对象的存储,以及遍历实现通知功能.