用ServerSocket 实现服务端与客户端之间信息传递

ServerSocket

具体用法参考jdk:
http://tool.oschina.net/apidocs/apidoc?api=jdk_7u4


为了方便理解ServerSocket
服务器与客户端的关系以及数据的交换
请看下图:

用ServerSocket 实现服务端与客户端之间信息传递_第1张图片


下面直接演示ServerSocket实现的几个功能:
一、 客户端服务端发信息给服务端
二、模拟一个广播电台(服务端向客服端发送信息)
三、模拟一个对讲机(半双工模式)只能交替通话,不能同时通话
四、做一个木马文件
五、客户端发送一个命令到服务端,服务端接收之后,在服务器执行这个命令,并把执行的结果返回给客户端

示例中所用到的java包:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

一、 客户端服务端发信息给服务端

/**
 * ServerSocket 实现服务端与客户端通讯
 * 
 * @author PeicongHe
 *
 */

public class ServerSocketDemo {
    /**
     * 步骤: 
     * 1 先创建一个服务端,端口号为:8888
     * 2 等待客户端连接 
     * 3 创建一个客户端的输入流(用于将信息发送给服务端) 
     * 4 服务端打印并显示信息
     */
    public static void test1() {
        try {
            ServerSocket serverSocket = new ServerSocket(8888); // 创建一个服务端,监听端口8888
            Socket socket = serverSocket.accept(); // 等待客户端连接过来
            System.out.println("来客IP: " + socket.getInetAddress()); // 获取来客的IP地址
            InputStream is = socket.getInputStream();// 客户端的输入流
            Scanner sc = new Scanner(is);
            String msg = "";
            while (sc.hasNextLine()) {
                msg = sc.nextLine();
                System.out.println(msg);
                if (msg.equals("exit")) {
                    System.out.println("我要退出!");
                    System.exit(0);
                }
            }
            sc.close();
            is.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public Static void main(String[] args){
        test1();
    }
}

用ServerSocket 实现服务端与客户端之间信息传递_第2张图片
用ServerSocket 实现服务端与客户端之间信息传递_第3张图片
用ServerSocket 实现服务端与客户端之间信息传递_第4张图片


/**
     * 增加自动回复功能 
     * 步骤: 
     *  1 在获取客户端输入流前添加一个客户端输出流(用于输出自动回复内容)
     *  2 打印输出流信息
     *  3  刷新打印
     */
    public static void test2() {
        try {
            ServerSocket serverSocket = new ServerSocket(8888);
            Socket socket = serverSocket.accept();
            System.out.println("来客ip: " + socket.getInetAddress());

            // 增加一个自动回复
            OutputStream os = socket.getOutputStream();// 添加一个客户端输出
            PrintWriter pw = new PrintWriter(os);// 打印出来
            pw.print("welcome to my home!");// 打印的信息
            pw.flush();// 刷新打印

            InputStream is = socket.getInputStream();
            Scanner sc = new Scanner(is);
            String msg = "";
            while (sc.hasNextLine()) {
                msg = sc.nextLine();
                System.out.println(msg);
                if (msg.equals("exit")) {
                    System.out.println("再见!我要退出!");
                    System.exit(0);
                }
            }
            sc.close();
            is.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

用ServerSocket 实现服务端与客户端之间信息传递_第5张图片


二、模拟一个广播电台(服务端向客服端发送信息)

    /**
     * 模拟一个广播电台,特点是只能服务端说话,不能客户端说话 
     * 步骤:
     * 1 创建一个服务端 
     * 2 接收一个客户端
     * 3 创建一个服务端的输入流(用于存储系统输入的数据流)
     * 4 创建一个客服的输出流(用于在客服上显示出数据)
     * 5 扫描打印,刷新打印
     */
     public static void broadcast(){
        try {
            ServerSocket server = new ServerSocket(8888);// 创建一个服务端,监听端口8888
            Socket socket = server.accept();// 等待客户端连接过来
            System.out.println("Ip: "+socket.getLocalAddress()+" 成功接入! ");

            OutputStream serverops1 = socket.getOutputStream();// 获取来客的IP地址
            //自动回复
            PrintWriter pw1 = new PrintWriter(serverops1);
            pw1.write("欢迎接入服务器!");
            pw1.flush();

            InputStream serverips = System.in;//在服务端输入广播内容做为输入流
            OutputStream serverops2 = socket.getOutputStream();//输出流用于传输信息给客户端
            PrintWriter pw = new PrintWriter(serverops2);
            //获取信息
            Scanner sc = new Scanner(serverips);
            String msg="";
            while(sc.hasNextLine()){
                msg = sc.nextLine();
                pw.println(msg);//输出信息
                pw.flush();
                if(msg.equals("exit")){
                    System.out.println("服务端讲话完毕,再见!");
                    System.exit(0);
                }
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

用ServerSocket 实现服务端与客户端之间信息传递_第6张图片
用ServerSocket 实现服务端与客户端之间信息传递_第7张图片


三、模拟一个对讲机(半双工模式)只能交替通话,不能同时通话

/**
     *  步骤:
     *  1 创建服务端 
     *  2 接收一个客户端 
     *  3 创建一个服务端的输入流(用于在服务端输入)
     *  4 创建一个客户端的输出流(用于在客户端显示)
     *  5 创建一个客户端的输入流 (用于在服务端显示)
     *  6 获取客户端发送的信息
     *  7 每次客户端输入一段话过来,我们都要从键盘输入一段话,并且发送给客户端
     */
        public static void connunication(){
        try {
            ServerSocket server = new ServerSocket(8888);// 创建一个服务端,监听端口8888
            Socket socket = server.accept();//接收一个客户端 

            Scanner scannerSystemIn = new Scanner(System.in);//创建一个服务端的输入流(用于在服务端输入)
            PrintWriter pw = new PrintWriter(socket.getOutputStream());//创建一个客户端的输出流(用于在客户端显示)
            Scanner scanner =new Scanner(socket.getInputStream());//创建一个客户端的输入流 (用于在服务端显示)

            String msg = "";
            String serverMsg ="";
            while(scanner.hasNextLine()){//获取客户端发送的信息
                msg=scanner.nextLine();
                System.out.println("客户端的输入: "+msg);
                //当输入exit 退出循环,结束通信
                if(msg.equals("exit")||serverMsg.equals("exit")){
                    System.out.println("退出连接!");
                    System.exit(0);
                }
                //每次客户端输入一段话过来,我们都要从键盘输入一段话,并且发送给客户端
                if(scannerSystemIn.hasNextLine()){
                    serverMsg = scannerSystemIn.nextLine();
                    System.out.println("服务端输入: " + serverMsg);
                    pw.println("服务端说:"+serverMsg);
                    pw.flush();
                }
            }
            //关闭流
            pw.close();
            scannerSystemIn.close();
            scanner.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

用ServerSocket 实现服务端与客户端之间信息传递_第8张图片
用ServerSocket 实现服务端与客户端之间信息传递_第9张图片


四、做一个木马文件

    /**
     * 客户端可以通过输入一个文件名传给服务端,服务端就会根据文件的地址,将文件的内容返回给客户端
     */
     public static void test5() {
        try {
            // 1:创建一个服务端,监听一个端口
            ServerSocket serverSocket = new ServerSocket(8888);
            // 2:获取一个客户端对象
            Socket socket = serverSocket.accept();

            InputStream is = socket.getInputStream();
            Scanner scanner = new Scanner(is);
            PrintWriter pw = new PrintWriter(socket.getOutputStream());
            while (scanner.hasNextLine()) {
                // 3 接受客户端的一个文件名
                String fileName = scanner.nextLine();
                // 4:读取文件
                String content = getContentFromFile(fileName);
                // 5:把文件内容返回给客户端
                pw.println(content);
                pw.flush();
            }
            is.close();
            socket.close();
            pw.close();

            // 4:
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

用ServerSocket 实现服务端与客户端之间信息传递_第10张图片用ServerSocket 实现服务端与客户端之间信息传递_第11张图片
用ServerSocket 实现服务端与客户端之间信息传递_第12张图片


五、客户端发送一个命令到服务端,服务端接收之后,在服务器执行这个命令,并把执行的结果返回给客户端

    /**
     * 功能: 客户端发送命令控制服务端,服务端返回执行结果给客户端
     * 步骤:
     * 1、获取客户端发送给服务端的命令
     * 2、服务器运用进程的语句执行命令,保存执行的结果
     * 3、判断执行结果
     * 4、将执行的结果发送给客户端
     */
    public static void test() {
        try {
            ServerSocket server = new ServerSocket(8888);
            // 由于我们平时测试的时候,每次出错或者每次在客户端断开连接的时候,服务端都会自动断开
            // 为了解决这个问题,我们写了一个循环,当一个连接退出时,服务端自动进入下一个连接

            while (true) {
                Socket socket = server.accept();

                Scanner scanner = new Scanner(socket.getInputStream());
                PrintWriter pw = new PrintWriter(socket.getOutputStream());

                String command = "";
                String p1Content = "";
                String p2Content = "";
                // String p1go = "";
                while (scanner.hasNextLine()) {
                    command = scanner.nextLine();
                    Process p = Runtime.getRuntime().exec(command);
                    // 需要从进程执行后的结果中得到一个输入流,这里我们想要的信息
                    Scanner p1go = new Scanner(p.getInputStream());
                    while (p1go.hasNextLine()) {// 输出到客户端
                        p1Content = p1go.nextLine();
                        pw.println(p1Content);
                        pw.flush();
                    }
                    // 如果命令执行错误,就会有一个错误流
                    Scanner p2er = new Scanner(p.getErrorStream());
                    while (p2er.hasNextLine()) {
                        p2Content = p2er.nextLine();
                    }
                    // 如果错误流不为空,就把错误信息输出到客户端
                    if (!p2Content.equals("")) {
                        pw.print(p2Content);
                        pw.flush();
                    }
                }
            }

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

用ServerSocket 实现服务端与客户端之间信息传递_第13张图片

你可能感兴趣的:(Java)