七、Java通信基础-Socket

2019-07-24  本文已影响0人  Lord丶轩莫言弃

1、概述

2、Java中的网络支持

针对网络通信的不同层次,Java提供的网络功能有四大类:

3、InetAddress类

package com.lord.quick;

import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * InetAddress类
 */
public class SocketTest {

    public static void main(String[] args) throws UnknownHostException {
        // 获取本机的InetAddress实例
        InetAddress address = InetAddress.getLocalHost();
        System.out.println("计算机名:" + address.getHostName());
        System.out.println("IP地址:" + address.getHostAddress());
        
        // 根据机器名获取InetAddress实例
        InetAddress address2 = InetAddress.getByName("Lord");
        System.out.println("计算机名:" + address2.getHostName());
        System.out.println("IP地址:" + address2.getHostAddress());
    }

}

4、URL

package com.lord.quick;

import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;

/**
 * URL常用方法
 */
public class SocketTest {

    public static void main(String[] args) throws UnknownHostException {
        try {
            // 创建URL实例
            URL zhihu = new URL("https://zhuanlan.zhihu.com");

            // ?号后面表示参数,#号后面表示锚点
            URL url = new URL(zhihu, "index.html?username=tom#test");
            System.out.println("协议:" + url.getProtocol());
            System.out.println("主机:" + url.getHost());

            // 如果未指定端口号,则使用默认端口号,此时,getPort()方法返回值为-1
            System.out.println("端口:" + url.getPort());

            System.out.println("文件路径:" + url.getPath());
            System.out.println("文件名:" + url.getFile());
            System.out.println("相对路径:" + url.getRef());
            System.out.println("查询字符串:" + url.getQuery());
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }

}
package com.lord.quick;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;

/**
 * 使用URL读取网页内容
 */
public class SocketTest {

    public static void main(String[] args) throws UnknownHostException {
        try {
            // 创建一个URL实例
            URL url = new URL("http://www.baidu.com");
            // 通过URL的openStream方法获取URL对象所表示的资源的字节输入流
            InputStream is = url.openStream();
            // 将字节输入流转换为字符输入流
            InputStreamReader isr = new InputStreamReader(is, "utf-8");
            // 为字符输入流添加缓冲
            BufferedReader br = new BufferedReader(isr);
            // 读取数据
            String data = br.readLine();
            // 循环读取数据
            while (data != null) {
                // 输出数据
                System.out.println(data);
                data = br.readLine();
            }
            br.close();
            isr.close();
            is.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

5、基于TCP协议的Socket通信,实现用户登录(单线程)

package com.lord.quick;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 基于TCP协议的Socket通信,实现用户登录
 * 服务器端
 */
public class Server {

    public static void main(String[] args) {

        try {
            // 1、创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口
            ServerSocket serverSocket = new ServerSocket(8888);
            System.out.println("***服务器即将启动,等待客户端的连接***");

            // 2、调用accept()开始监听,等待客户端连接
            Socket socket = serverSocket.accept();

            // 3、获取输入流,并读取客户端信息
            // 字节输入流
            InputStream is = socket.getInputStream();
            // 将字节流转换为字符流
            InputStreamReader isr = new InputStreamReader(is);
            // 为输入流添加缓冲
            BufferedReader br = new BufferedReader(isr);

            // 循环读取客户端的信息
            String info = null;
            while ((info = br.readLine()) != null) {
                System.out.println("我是服务器,客户端说:" + info);
            }

            // 关闭输入流
            socket.shutdownInput();

            // 4、获取输出流,响应客户端的请求
            OutputStream os = socket.getOutputStream();
            // 包装为打印流
            PrintWriter pw = new PrintWriter(os);
            pw.write("欢迎您!");
            // 调用flush方法,将缓存输出
            pw.flush();

            // 5、关闭资源
            pw.close();
            os.close();
            br.close();
            isr.close();
            is.close();
            socket.close();
            serverSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}
package com.lord.quick;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * 基于TCP协议的Socket通信,实现用户登录
 * 客户端
 */
public class Client {

    public static void main(String[] args) {

        try {
            // 1、创建客户端Socket,指定服务器地址和端口
            Socket socket = new Socket("127.0.0.1", 8888);

            // 2、获取输出流,向服务器端发送信息
            // 字节输出流
            OutputStream os = socket.getOutputStream();
            // 将输出流包装成打印流
            PrintWriter pw = new PrintWriter(os);
            pw.write("用户名:admin;密码:123");
            pw.flush();

            // 关闭输出流
            socket.shutdownOutput();

            // 3、获取输入流,并读取服务端的响应内容
            InputStream is = socket.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));

            String info = null;
            while ((info = br.readLine()) != null) {
                System.out.println("我是客户端,服务器说:" + info);
            }

            // 4、关闭资源
            br.close();
            is.close();
            pw.close();
            os.close();
            socket.close();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

6、基于TCP协议的Socket通信,实现用户登录(多线程)

package com.lord.quick;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;

/**
 *  服务器端线程处理类
 */
public class ServerThread extends Thread {
    // 和本线程相关的处理类
    Socket socket = null;

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

    // 执行线程操作,响应客户端请求
    @Override
    public void run() {
        InputStream is = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        OutputStream os = null;
        PrintWriter pw = null;

        try {
            // 获取输入流,并读取客户端信息
            is = socket.getInputStream();
            isr = new InputStreamReader(is);
            br = new BufferedReader(isr);

            // 循环读取客户端的信息
            String info = null;
            while ((info = br.readLine()) != null) {
                System.out.println("我是服务器,客户端说:" + info);
            }

            // 关闭输入流
            socket.shutdownInput();

            // 获取输出流,响应客户端的请求
            os = socket.getOutputStream();
            pw = new PrintWriter(os);
            pw.write("欢迎您!");

            // 调用flush方法,将缓存输出
            pw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                // 关闭资源
                if (pw != null) {
                    pw.close();
                }
                if (os != null) {
                    os.close();
                }
                if (br != null) {
                    br.close();
                }
                if (isr != null) {
                    isr.close();
                }
                if (is != null) {
                    is.close();
                }
                if (socket != null) {
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

}
package com.lord.quick;

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 基于TCP协议的Socket通信,实现用户登录
 * 服务器端
 */
public class Server {

    public static void main(String[] args) {

        try {
            // 1、创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口
            ServerSocket serverSocket = new ServerSocket(8888);
            System.out.println("***服务器即将启动,等待客户端的连接***");
            Socket socket = null;
            // 记录客户端的数量
            int count = 0;
            // 循环监听等待客户端的连接
            while (true) {
                // 调用accept()开始监听,等待客户端连接
                socket = serverSocket.accept();
                // 创建一个新的线程
                ServerThread serverThread = new ServerThread(socket);
                // 启动线程
                serverThread.start();

                // 统计客户端的数量
                count++;
                System.out.println("客户端的数量:" + count);

                InetAddress address = socket.getInetAddress();
                System.err.println("当前客户端的IP:" + address.getHostAddress());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}
package com.lord.quick;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * 基于TCP协议的Socket通信,实现用户登录
 * 客户端
 */
public class Client {

    public static void main(String[] args) {

        try {
            // 1、创建客户端Socket,指定服务器地址和端口
            Socket socket = new Socket("127.0.0.1", 8888);

            // 2、获取输出流,向服务器端发送信息
            // 字节输出流
            OutputStream os = socket.getOutputStream();
            // 将输出流包装成打印流
            PrintWriter pw = new PrintWriter(os);
            pw.write("用户名:admin;密码:123");
            pw.flush();

            // 关闭输出流
            socket.shutdownOutput();

            // 3、获取输入流,并读取服务端的响应内容
            InputStream is = socket.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));

            String info = null;
            while ((info = br.readLine()) != null) {
                System.out.println("我是客户端,服务器说:" + info);
            }

            // 4、关闭资源
            br.close();
            is.close();
            pw.close();
            os.close();
            socket.close();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

7、UDP编程

8、基于UDP协议的Socket通信,实现用户登录

package com.lord.quick;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/**
 * 基于UDP协议的Socket通信,实现用户登录
 * 服务器端
 */
public class UDPServer {

    public static void main(String[] args) throws IOException {

        /**
         * 接收客户端发送的数据
         */
        // 1、创建服务器端DatagramSocket,指定端口
        DatagramSocket socket = new DatagramSocket(8800);
        // 2、创建数据报,用于接收客户端发送的数据
        byte[] data = new byte[1024];
        DatagramPacket packet = new DatagramPacket(data, data.length);
        // 3、接收客户端发送的数据,此方法在接收到数据报之前会一直阻塞
        System.out.println("***服务器已经启动,等待客户端发送数据***");
        socket.receive(packet);
        // 4、读取数据
        String info = new String(data, 0, packet.getLength());
        System.out.println("我是服务器,客户端说:" + info);

        /**
         * 向客户端响应数据
         */
        // 1、定义客户端的地址、端口、数据
        InetAddress address = packet.getAddress();
        int port = packet.getPort();
        byte[] data2 = "欢迎您!".getBytes();
        // 2、创建数据报,包含响应的信息
        DatagramPacket packet2 = new DatagramPacket(data2, data2.length, address, port);
        // 3、响应客户端
        socket.send(packet2);

        // 关闭资源
        socket.close();
    }

}
package com.lord.quick;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/**
 * 基于UDP协议的Socket通信,实现用户登录
 * 客户端
 */
public class UDPClient {

    public static void main(String[] args) throws IOException {

        /**
         * 向服务器端发送数据
         */
        // 1、定义服务器的地址、端口号、数据
        InetAddress address = InetAddress.getByName("localhost");
        int port = 8800;
        byte[] data = "用户名:admin;密码:123".getBytes();
        // 2、创建数据报,包含发送的信息
        DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
        // 3、创建DatagramSocket对象
        DatagramSocket socket = new DatagramSocket();
        // 4、向服务器端发送数据报
        socket.send(packet);

        /**
         * 接收服务器端响应的数据
         */
        // 1、创建数据报,用于接受服务器端响应的数据
        byte[] data2 = new byte[1024];
        DatagramPacket packet2 = new DatagramPacket(data2, data2.length);
        // 2、接收服务器端响应的数据
        socket.receive(packet2);
        // 3、读取数据
        String reply = new String(data2, 0, packet2.getLength());
        System.out.println("我是客户端,服务器说:" + reply);

        // 关闭资源
        socket.close();
    }

}
上一篇 下一篇

猜你喜欢

热点阅读