[2025.1.18 JavaSE学习]网络编程-1(InetAddress类 && Socket && TCP网络通信编程)

InetAddress类

相关方法

  • getLocalHost:获取本机InetAddress对象
  • getByName:根据指定主机名/域名获取ip地址对象
  • getHostName:获取InetAddress对象的主机名
  • getHostAddress:获取InetAddress对象的地址
//得到本机的InetAddress对象
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(localHost);//MyLapTop/xxx.xxx.xx.xxx

//根据指定主机名获取InetAddress对象
InetAddress host1 = InetAddress.getByName("MyLapTop");
System.out.println(host1);//输出和上面相同

//根据域名返回一个InetAddress对象
//获取百度
InetAddress host2 = InetAddress.getByName("www.baidu.com");
System.out.println(host2);//www.baidu.com/183.2.172.185

//通过InetAddress对象获取对应的地址
String hostAddress = host2.getHostAddress();
System.out.println(hostAddress);//183.2.172.185


Socket

基本介绍

  • 套接字(Socket)开发网络应用程序被广泛采用
  • 通信的两端都要有Socket,是两台机器间通信的端点
  • 网络通信其实就是Socket间的通信
  • Socket允许程序把网络连接当成一个,数据在两个Socket间通过I/O传输
  • 一般主动发起通信的应用程序属于客户端等待通信请求的为服务端
  • 示意图(类似ROS中的Client - Server机制)

image

  • Socket有两种编程方式:
  • TCP编程,可靠性强
  • UDP编程,可靠性弱


TCP网络通信编程实例(在不同机器上进行通信,为方便演示写在同一机器上)

实例1 - 字节读写

image

  • Client_.java
package events;

import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;

public class Client_ {

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

        //连接这台机器(这里是本机)的9999端口
        //如果连接成功,返回Socket对象
        System.out.println("客户端连接中...");
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
        System.out.println("客户端连接成功,Port:9999");

        //连接上后,生成socket进行output
        //得到该socket关联的输出流对象
        OutputStream outputStream = socket.getOutputStream();

        //客户端写数据
        outputStream.write("hello server".getBytes());

        //关闭流对象和socket
        outputStream.close();
        socket.close();
        System.out.println("客户端退出");
    }
}
  • Server_.java
package events;

import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server_ {
    public static void main(String[] args) throws Exception{
        //服务端9999端口监听,等到连接
        //要求本机没有其他服务在监听9999端口
        //serverSocket可以通过accept()返回多个Socket(多个客户端连接服务端的并发)
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("服务端等待连接");

        //当有客户端连接9999端口时,则会返回一个Socket对象,程序继续
        Socket socket = serverSocket.accept();
        System.out.println("服务端连接成功:" + socket.getClass());

        //通过该socket获取输入流,读取数据
        InputStream inputStream = socket.getInputStream();
        byte[] buff = new byte[1024];
        int readLen = 0;
        while((readLen = inputStream.read(buff)) != -1){
            System.out.println(new String(buff, 0, readLen));
        }

        //关闭流和socket
        inputStream.close();
        socket.close();
        serverSocket.close();
    }
}

实例2 - 字节读写

image

  • Client_.java
package events;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;

public class Client_ {

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

        //连接这台机器(这里是本机)的9999端口
        //如果连接成功,返回Socket对象
        System.out.println("客户端连接中...");
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
        System.out.println("客户端连接成功,Port:9999");

        //连接上后,生成socket进行output
        //得到该socket关联的输出流对象
        OutputStream outputStream = socket.getOutputStream();

        //客户端写数据
        outputStream.write("hello server".getBytes());

        //设置写入结束标记
        socket.shutdownOutput();

        //得到该socket关联的输入流对象
        InputStream inputStream = socket.getInputStream();
        byte[] buff = new byte[1024];
        int readLen = 0;
        while((readLen = inputStream.read(buff)) != -1){
            System.out.println(new String(buff, 0, readLen));
        }

        //关闭流对象和socket
        outputStream.close();
        inputStream.close();
        socket.close();
        System.out.println("客户端退出");
    }
}
  • Server_.java
package events;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server_ {
    public static void main(String[] args) throws Exception{
        //服务端9999端口监听,等到连接
        //要求本机没有其他服务在监听9999端口
        //serverSocket可以通过accept()返回多个Socket(多个客户端连接服务端的并发)
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("服务端等待连接");

        //当有客户端连接9999端口时,则会返回一个Socket对象,程序继续
        Socket socket = serverSocket.accept();
        System.out.println("服务端连接成功:" + socket.getClass());

        //通过该socket获取输入流,读取数据
        InputStream inputStream = socket.getInputStream();
        byte[] buff = new byte[1024];
        int readLen = 0;
        while((readLen = inputStream.read(buff)) != -1){
            System.out.println(new String(buff, 0, readLen));
        }

        //通过该socket获取输出流,写数据
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("hello, client".getBytes());

        //设置写入结束标记
        socket.shutdownOutput();

        //关闭流和socket
        inputStream.close();
        outputStream.close();
        socket.close();
        serverSocket.close();
    }
}



实例3 - 字符读写(需要使用转换流)

image

  • Client_.java
package events;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;

public class Client_ {

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

        //连接这台机器(这里是本机)的9999端口
        //如果连接成功,返回Socket对象
        System.out.println("客户端连接中...");
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
        System.out.println("客户端连接成功,Port:9999");

        //连接上后,生成socket进行output
        //得到该socket关联的输出流对象
        OutputStream outputStream = socket.getOutputStream();
        //转为字符流
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
        //客户端写数据
        bufferedWriter.write("hello server - Char");
        bufferedWriter.newLine();//插入换行,表示写入结束,要求对方使用readLine
        bufferedWriter.flush();//字符流需要手动刷新

        //字符流不需要设置写入结束标记
        //socket.shutdownOutput();

        //得到该socket关联的输入流对象
        InputStream inputStream = socket.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        bufferedReader.readLine();

        //关闭流对象和socket
        outputStream.close();
        inputStream.close();
        socket.close();
        System.out.println("客户端退出");
    }
}
  • Server_.java
package events;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Server_ {
    public static void main(String[] args) throws Exception{
        //服务端9999端口监听,等到连接
        //要求本机没有其他服务在监听9999端口
        //serverSocket可以通过accept()返回多个Socket(多个客户端连接服务端的并发)
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("服务端等待连接");

        //当有客户端连接9999端口时,则会返回一个Socket对象,程序继续
        Socket socket = serverSocket.accept();
        System.out.println("服务端连接成功:" + socket.getClass());

        //通过该socket获取输入流,读取数据
        InputStream inputStream = socket.getInputStream();
        //转为字符流,readLine读取
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        bufferedReader.readLine();

        //通过该socket获取输出流,写数据
        OutputStream outputStream = socket.getOutputStream();
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
        bufferedWriter.write("hello client - Char");
        bufferedWriter.newLine();
        bufferedWriter.flush();

        //设置写入结束标记
        socket.shutdownOutput();

        //关闭流和socket
        inputStream.close();
        outputStream.close();
        socket.close();
        serverSocket.close();
    }
}


实例4 - 文件传送

image

  • StreamUtils.java
package events;

import jdk.internal.util.xml.impl.Input;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;

public class StreamUtils {
    /**
     * 把输入流转为byte[],即把文件的内容读入到byte[]
     * @param is
     * @return
     * @throws Exception
     */
    public static byte[] streamToByteArray(InputStream is) throws Exception{
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] b = new byte[1024];
        int len;
        while((len = is.read(b))!=-1){
            bos.write(b,0, len);
        }
        byte[] array = bos.toByteArray();
        bos.close();
        return array;
    }

    /**
     *把InputStream转换为哦String
     * @param is
     * @return
     * @throws Exception
     */
    public static String streamToString(InputStream is) throws Exception{
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder builder = new StringBuilder();
        String line;
        while((line = reader.readLine())!=null){
            builder.append(line+"\r\n");
        }
        return builder.toString();
    }
}
  • Client_.java
package events;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;

public class Client_ {

    public static void main(String[] args) throws Exception {
        //客户端连接服务端,传本机ip和端口号
        Socket socket = new Socket(InetAddress.getLocalHost(), 8888);

        //创建读取磁盘文件的输入流
        String filePath = "C:\\Users\\luvis\\Pictures\\Screenshots\\1.png";
        BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(filePath));

        //图片的字节数组
        byte[] bytes = StreamUtils.streamToByteArray(bufferedInputStream);

        //获取输出流,写入图片字符数组
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(socket.getOutputStream());
        bufferedOutputStream.write(bytes);
        socket.shutdownOutput();//结束标记
        bufferedInputStream.close();

        //接受回复
        InputStream inputStream = socket.getInputStream();
        String s = StreamUtils.streamToString(inputStream);
        System.out.println("接收到回复:"+s);

        bufferedOutputStream.close();
        inputStream.close();
        socket.close();
    }
}
  • Server_.java
package events;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Server_ {
    public static void main(String[] args) throws Exception{
        //服务端监听
        ServerSocket serverSocket = new ServerSocket(8888);

        //等待连接
        System.out.println("服务端在8888端口监听");
        Socket socket = serverSocket.accept();

        //读取客户端发送的图片字节数组
        //得到输入流
        BufferedInputStream bufferedInputStream = new BufferedInputStream(socket.getInputStream());
        byte[] bytes = StreamUtils.streamToByteArray(bufferedInputStream);

        //将字节数组写入到指定路径
        String filePath = "C:\\Users\\luvis\\Desktop\\w\\1.png";
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(filePath));
        bufferedOutputStream.write(bytes);

        //回复收到
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        bufferedWriter.write("收到图片");
        bufferedWriter.flush();
        socket.shutdownOutput();


        bufferedOutputStream.close();
        bufferedInputStream.close();
        bufferedWriter.close();
        socket.close();
        serverSocket.close();

    }
}
posted @ 2025-01-18 23:58  Luna-Evelyn  阅读(27)  评论(0)    收藏  举报