首页 > 编程语言 >java的网络知识

java的网络知识

时间:2023-01-12 16:57:12浏览次数:40  
标签:java socket 知识 网络 System close out 服务端 客户端

本文主要讲述java的网络知识,以及网络编程所需要使用的类。

一. InetAdress类

InetAddress类,用于获取主机名和IP地址【域名】

public class InetAddressTest {
    public static void main(String[] args) throws UnknownHostException {
        // 1.获取本机的Inet4Address对象
        InetAddress localHost = Inet4Address.getLocalHost();
        System.out.println("本地主机的InetAddress对象: " + localHost);
        // 2.根据主机的名称,获取Inet4Address对象
        InetAddress host1 = Inet4Address.getByName("DESKTOP-TIT5KO3");
        System.out.println("本地主机的InetAddress对象: " + host1);
        // 3.根据域名,获取InetAddress对象
        InetAddress host2 = Inet4Address.getByName("www.baidu.com");
        System.out.println("百度的InetAddress对象: " + host2);
        // 4.根据InetAddress对象,获取IP地址
        String hostAddress = host2.getHostAddress();
        System.out.println("IP地址: " + hostAddress);
        // 5.根据InetAddress对象,获取主机名\域名
        String hostName = host2.getHostName();
        System.out.println("域名: " + hostName);
    }
}

二. Socket类

案例一:使用字节流,编写服务端和客户端,要求服务端接受客户端发过来的数据,并显示在控制台上

服务端:

public class SocketTCPServer {
    public static void main(String[] args) throws Exception{
        // 1. 服务端,创建ServerSocket对象,在本主机监听9999端口,等待客户端的链接
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("服务端的serverSocket正在监听9999端口,等待连接");
        // 2. 客户端如果链接了9999端口,返回socket对象;否则,程序阻塞,无法向下执行
        //    serverSocket.accept()会返回多个Socket【多个客户端并发】
        Socket socket = serverSocket.accept();
        System.out.println("服务器端返回的serverSocket: " + socket.getClass());
        // 3. 客户端socket对象写入数据,服务端socket对象获取输入流 getOutputStream,读入数据
        InputStream inputStream = socket.getInputStream();
        // 4. 使用inputStream读取数据
        byte[] bytes = new byte[1024]; // 读取数据所需要的字节数组
        int readLen = 0; // 读取数据的长度
        // 读取长度是-1,则表示数据已经读完
        while((readLen = inputStream.read(bytes)) != -1){
            // 每次按照bytes数组长度,读取数据内容,读取完毕,返回-1.
            // new String(bytes,0,readLen),防止不足bytes数组长度的数据无法显示
            System.out.print(new String(bytes,0,readLen));
        }
        System.out.println("服务器端读取数据完毕");
//         5. 关闭输入流和socket【服务端】
        inputStream.close();
        socket.close();
        serverSocket.close();

    }
}

客户端:

public class SocketTCPClient01 {
    public static void main(String[] args) throws Exception{
        // 1. 客户端,创建socket对象 new Socket(ip地址,端口号)
        // ip地址,是服务端所在主机的ip地址,端口号是服务端监听的端口号
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
        System.out.println("客户端返回的serverSocket: " + socket.getClass());
        // 2. 通过socket对象,获取socket的输出流getOutputStream(),写入数据
        OutputStream outputStream = socket.getOutputStream();
        // 3. 使用OutputStream写入数据
        outputStream.write("hello,I am client01\n".getBytes());
        // 4. 关闭输出流和socket【客户端】
        outputStream.close();
        socket.close();
//        System.out.println("客户端退出");

    }
}

案例二:使用字节流,编写服务端和客户端,要求服务端接收客户端的消息A,发送消息B;客户端发送消息A,接收服务端的消息B

vip

错误写法:

服务端:

public class SocketServer {
    public static void main(String[] args) throws Exception{
        // 1. 创建socketServer对象,端口号9999
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("启动服务器...");
        // 2. 监听客户端
        Socket socket = serverSocket.accept();
        // 3. 获取输入流
        InputStream inputStream = socket.getInputStream();
        int readLen = 0;
        byte[] bytes = new byte[1024];
        while((readLen = inputStream.read(bytes)) != -1){
            String s = new String(bytes, 0, readLen);
            System.out.println(s);
        }
        // 4. 获取输出流
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("hello Client".getBytes());// 5. 关闭输入输出流
        outputStream.close();
        inputStream.close();
        socket.close();
        serverSocket.close();
    }
}

客户端:

public class SocketClient01 {
    public static void main(String[] args) throws IOException {
        // 1. 创建socket对象
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
        System.out.println("启动客户端...");
        // 2. 获取OutPut
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("hello Server".getBytes());
        // 3. 获取输入流
        InputStream inputStream = socket.getInputStream();
        byte[] bytes = new byte[1024];
        int readLen = 0;
        while((readLen = inputStream.read(bytes)) != -1){
            String s = new String(bytes, 0, readLen);
            System.out.println(s);
        }
        // 4. 关闭输入输出流
        outputStream.close();
        inputStream.close();
        socket.close();
    }
}

此时,启动服务端,监听客户端是否链接,启动客户端,在客户端写入hello Server,服务端读取到了数据,并将其显示,但是服务端并不知道客户端在什么时候写入结束,因此服务端会在数据连接中一直进行读操作,客户端在等待接收服务端写入的数据,随即发生了服务端和客户端都阻塞的现象。

正确写法:

// 设置输出的结束标记
socket.shutdownOutput();
// 设置输入的结束标记
socket.shutdownInput();

当写入或者读取结束时,要设置写入或者读取结束的标记

服务端:

public class SocketServer {
    public static void main(String[] args) throws Exception{
        // 1. 创建socketServer对象,端口号9999
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("启动服务器...");
        // 2. 监听客户端
        Socket socket = serverSocket.accept();
        // 3. 获取输入流
        InputStream inputStream = socket.getInputStream();
        int readLen = 0;
        byte[] bytes = new byte[1024];
        while((readLen = inputStream.read(bytes)) != -1){
            String s = new String(bytes, 0, readLen);
            System.out.println(s);
        }
        // 设置输入结束的标记
        socket.shutdownInput();
        // 4. 获取输出流
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("hello Client".getBytes());
        // 设置输出的结束标记
        socket.shutdownOutput();

        // 5. 关闭输入输出流
        outputStream.close();
        inputStream.close();
        socket.close();
        serverSocket.close();
    }
}

客户端:

public class SocketClient01 {
    public static void main(String[] args) throws IOException {
        // 1. 创建socket对象
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
        System.out.println("启动客户端...");
        // 2. 获取OutPut
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("hello Server\n".getBytes());
        // 设置输出的结束标记
        socket.shutdownOutput();
        // 3. 获取输入流
        InputStream inputStream = socket.getInputStream();
        byte[] bytes = new byte[1024];
        int readLen = 0;
        while((readLen = inputStream.read(bytes)) != -1){
            String s = new String(bytes, 0, readLen);
            System.out.println(s);
        }
        // 设置输入的结束标记
        socket.shutdownInput();
        // 4. 关闭输入输出流
        outputStream.close();
        inputStream.close();
        socket.close();
    }
}

运行结果:

vip

vip

 

标签:java,socket,知识,网络,System,close,out,服务端,客户端
From: https://www.cnblogs.com/zwgitOne123/p/17047093.html

相关文章