Java网络编程(2)

构建Tcp客户端

由于是一个很简单的demo,我创建一个普通的java项目就可以,然后创建一个Client类:

 public static void main(String[] args) throws IOException {
        Socket socket = new Socket();
        //设置 超时时间
        socket.setSoTimeout(3000);
        //连接本地 端口2000 超时时间为3000毫秒
        socket.connect(new InetSocketAddress(Inet4Address.getLocalHost(),2000), 3000);

        System.out.println("已经发起服务器连接。。。");
        System.out.println("客户端信息:" + socket.getLocalAddress() + ":" + socket.getLocalPort());
        System.out.println("服务器信息:" + socket.getInetAddress() + ":" + socket.getPort());
        try {
            todo(socket);
        }catch (Exception e) {
            System.out.println("异常关闭");
        }

        socket.close();
        System.out.println("客户端退出");
    }

    private static void todo(Socket client) throws IOException {
        InputStream in = System.in;
        BufferedReader input = new BufferedReader(new InputStreamReader(in));

        //得到输入流
        OutputStream out = client.getOutputStream();
        PrintStream printStream = new PrintStream(out);

        //得到输入流 
        InputStream inputStream = client.getInputStream();
        BufferedReader buf = new BufferedReader(new InputStreamReader(inputStream));

        boolean flag = true;
        do {
            String str = input.readLine();
            //发送到服务器
            printStream.println(str);

            String echo = buf.readLine();

            if ("bye".equalsIgnoreCase(echo)) {
                flag = false;
            } else {
                System.out.println(echo);
            }
        }while (flag);
        buf.close();
        printStream.close();
        System.out.println("客户端已关闭");

    }
}

注意由于我们使用的是IpV4这里我们使用的是Inet4Address这个类,并且我们创建了一个Socket对象。这个Socket对象可以获取客户端和服务器的信息。如ip地址和端口号。
我们还声明了一个静态的todo方法并且带了Socket参数,这个方法主要是使用键盘输入流来向服务器发送信息。我们得到键盘输入流和,需要使用BufferedReader这个类处理,并且间接的使用InputStreamReader将键盘输入流传入进去。

我们得到输入流client.getInputStream(),我们使用do while 循环可以不停的读取键盘输入的内容,最重要的是里面的if语句,这里我们对客户端输入的内容如果是bye那么就关闭客户端。

构建Tcp服务端

我们创建一个Server类:

public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(2000);

        System.out.println("服务器准备就绪...");
        System.out.println("服务器信息:" + server.getInetAddress() + ":" + server.getLocalPort());

        //等待客户端连接
        for(;;) {
            //得到客户端
            Socket client = server.accept();
            //客户端构建异步线程
            ClientHandler clientHandler = new ClientHandler(client);
            //启动线程
            clientHandler.start();
        }
    }

    private static class  ClientHandler extends Thread {
        private Socket socket;
        private boolean flag = true;

        public ClientHandler(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            super.run();
            System.out.println("新客户端连接:" + socket.getInetAddress() + ":" + socket.getPort());
            try {
                //得到打印流 用于数据输出,服务器回送数据使用
                PrintStream socketOutput = new PrintStream(socket.getOutputStream());
                //得到输入流,用于接受客户端数据
                BufferedReader socketInput = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                do {
                    String str = socketInput.readLine();
                    if ("bye".equalsIgnoreCase(str)) {
                        flag = false;
                        //回送数据
                        socketOutput.println("bye");
                    } else {
                        System.out.println(str);
                        socketOutput.println("回送:" + str.length());
                    }
                }while (flag);
                socketInput.close();
                socketOutput.close();
            }catch (Exception e) {
                System.out.println("连接断开");
            }finally {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            System.out.println("客户端已经关闭:" + socket.getInetAddress() + ":" + socket.getPort());

        }
    }
}

这里创建服务器端我们使用的是ServerSocket 并且指向端口2000,并且打印了服务器的地址和端口。

然后使用了没有条件的for循环,一直获取客户端。在这个for循环中,我们构建了一个异步线程ClientHandler,ClientHandler是一个静态类并且继承了线程类Thread,并且在ClientHandler类中,定义了两个成员变量Socket和一个标记flag。ClientHandler由于继承了Thread类那么就要重写run方法,
在这个run方法中前面的流程和客户端是一样的。通过回送的数据判断如果是bye那么就向客户端回送这个bye这个消息告诉客户端。服务器已经关闭,不要再发送信息给我了。我已经收不到了。 最后调用clientHandler.start方法启动该线程。

那么我们的服务器和客户端就编写完成,现在我们来测试一下,运行服务端:
Java网络编程(2)_第1张图片
我们在运行客户端:
可以看到服务端发现来客户端的连接如下图:
Java网络编程(2)_第2张图片
客户端也发现了服务端:
Java网络编程(2)_第3张图片

我们在客户端发一些字符串来测试:
Java网络编程(2)_第4张图片

服务器接收情况如下:
Java网络编程(2)_第5张图片

那么当我在客户端输入bye的字符串如下:
Java网络编程(2)_第6张图片
此时客户端已经关闭了。

服务器也发现了客户端关闭了。

Java网络编程(2)_第7张图片
如果还需要和服务器交互,那么客户端只需要重写连接即可。

总结

上面代码很简单。以简单的代码,让大家知道如何通过简单的代码实现tcp服务端和客户端是如何进行连接,会话的。以及如何传输数据。可以看到我们使用的api都是java.net包下为我们提供的api,这些api为我们提供了非常大的便利。让我们网络编程更加的简单。

你可能感兴趣的:(网络编程)