InetAddress 根据域名得到IP地址或名称

没有构造方法,通过:
(1)InetAddress i1 =InetAddress.getByName(String)返回一个InetAddress实例。
(2)如果一个地址有多个ip地址,比如google,有3个ip地址,就调用InetAddress[] i2 =
InetAddress.getAllByName(String);
InetAddress.getLocalhost()获得本机的InetAddress实例。

package Day22_net;

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

/**
 * @author Aoman_Hao
 */
public class InetTest {

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

        //提供主机名获取主机的IP
        InetAddress byName = InetAddress.getByName("AomanHao");
        System.out.println("主机IP:"+byName);

        //提供主机IP获取主机名,主机IP是之前返回值
        String hostName = byName.getHostName();
        System.out.println("主机名:"+hostName);


    }   

}
输出:
主机IP:AomanHao/192.168.0.111
主机名:AomanHao

Java网络程序都建立在TCP/IP协议基础上,在应用层实现。传输层向应用层提供了套接字Socket接口,Socket封装了下层的数据传细节,应用层的程序通过Socket来建立与远程主机的连接,以及数据传输,如下图所示:

网络编程_数据


UDP协议

  • UDP协议(发送端和接收端),不需要建立连接通道
    发送端 步骤:
    1)创建UDP协议发送端的Socket对象
    2)创建数据报包:通过这个数据包将数据发送到接收端
    3)调用UDP协议发送端发送的方法
    4)关闭资源
    UDP协议的接收端
    1)创建接收端的Socket对象
    2)创建一个数据报包接收发送端发送来的数据报包(接收容器)
    4)解析数据报包里面的实际数据,显示在控制台上
    5)关闭资源
发送类:
package Day22_net;

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

/**
 * @author Aoman_Hao
 */
public class SendDemo {

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

        //创建Socket对象
        DatagramSocket ds = new DatagramSocket();

        //创建InetAddress对象,Ip地址对象
        InetAddress address = InetAddress.getByName("192.168.0.111") ;      

        //发送数据内容
        String s = "刘诗诗最美丽";
        byte[] by = s.getBytes();

        //创建数据报包
        DatagramPacket dp = new DatagramPacket(by, by.length, address, 55);

        //调用send方法
        ds.send(dp);

        //关闭
        ds.close();


    }
}

接收类:
package Day22_net;

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

/**
 * @author Aoman_Hao
 */
public class ReceiveDemo {

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

        // 创建Socket对象 ----datagramsocket
        DatagramSocket ds = new DatagramSocket(55);

        byte[] by = new byte[1024];
        // 创建数据报包----datagrampacket
        DatagramPacket dp = new DatagramPacket(by, by.length);

        // 调用接收方法 ---receive
        ds.receive(dp);

        // 解析数据
        // 通过数据报包得到IP对象,地址
        InetAddress address = dp.getAddress();
        String hostAddress = address.getHostAddress();

        // 解析数据---getdata
        byte[] by1 = dp.getData();
        int length = dp.getLength();
        // 重建字符串
        String s = new String(by1, 0, length);

        System.out.println(s);
        ds.close();

    }

}

注:先运行接收端,在运行发送端
输出:
刘诗诗最美丽

接收类的receive采用阻塞式方法(即等待发送端发送数据,只要没有数据,就一直等待,有数据的话将数据显示控制)


循环录入,屏幕录入数据的效果

发送端:
package Day22_net;

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

/**
 * 
 * 屏幕录入数据,udp发送,接收
 * @author Aoman_Hao
 */
public class SendDemo2 {
public static void main(String[] args) throws IOException {

        // 创建socket对象
        DatagramSocket s = new DatagramSocket();

        // 用IO流屏幕录入数据,有readline方法可用
        BufferedReader sd = new BufferedReader(new InputStreamReader(System.in));

        // 循环录入,一句一句录入
        String line = null;
        while ((line = sd.readLine()) != null) {
            byte[] by = line.getBytes();
            // 创建数据报包
            DatagramPacket dp = new DatagramPacket(by, by.length,
                    InetAddress.getByName("192.168.0.111"), 55);
            s.send(dp);

        }
        s.close();
        sd.close();
    }
}
接收端:
package Day22_net;

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

/**
 * @author Aoman_Hao
 */
public class ReceiveDemo2 {

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

        //创建socket对象,输入对应端口
        DatagramSocket ds = new DatagramSocket(55);

        byte[] by = new byte[1024];
        //创建数据报包
        DatagramPacket dp = new DatagramPacket(by, by.length);

        while(true){
            //接收数据
            ds.receive(dp);

            //解析数据 getData,getLength
            byte[] bs = dp.getData();
            int length = dp.getLength();

            String s = new String(bs, 0, length);

            //读取发送端IP地址
            String hostAddress = dp.getAddress().getHostAddress();

            System.out.println("IP地址"+hostAddress+"发送"+s);

        }

    }

}

注:接收端要不停接收数据,不需要关闭
输出:
(发送端):
刘诗诗美丽
蓉儿更美
(接收端):
IP地址192.168.0.111发送刘诗诗美丽
IP地址192.168.0.111发送蓉儿更美

TCP网络编程

构造方法:

ServerSocket() ~创建非绑定服务器套接字。

ServerSocket(int port) ~创建绑定到特定端口的服务器套接字。

ServerSocket(int port, int backlog) ~利用指定的 backlog
创建服务器套接字并将其绑定到指定的本地端口号。

ServerSocket(int port, int backlog, InetAddress bindAddr) ~使用指定的端口、侦听
backlog 和要绑定到的本地 IP 地址创建服务器。

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

/**
 * @author Aoman_Hao
 */
public class TcpServerDemo {

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

        // 构造服务器端的socket对象
        ServerSocket ss = new ServerSocket(5);

        // 创建监听对象
        Socket s = ss.accept();

        // 创建输入流对象
        InputStream is = s.getInputStream();

        // 遍历读取数据,read()方法读取
        while (true) {
            byte[] by = new byte[1024];
            int len = is.read(by);
            String s1 = new String(by, 0, len);
            System.out.println(s1 + "\t树洞准奏");
        }
        // 服务器端一直工作,不需要关闭流
    }

}

客户端:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;



/**
 * TCP 客户端,服务器端通信互联(屏幕录入数据)
 * @author Aoman_Hao
 */
public class TcpClientDemo {

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

        // 构造客户端的socket对象
        Socket s = new Socket("192.168.0.111", 5);

        // 屏幕录入打印输出流
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("输出你的祝福或者愿望给树洞,回复“0”结束说话");

        // 读取输出流
        OutputStream os = s.getOutputStream();

        // 遍历写在流中
        String line = null;
        // 判断如果只输入字符“0”则退出输出入,退出客户端
        while ((line = br.readLine()) != null) {
            if (line.equals("0") ) {
                break;
            } else {
                os.write(line.getBytes());
            }
        }

        // 关闭流
        br.close();
        os.close();

    }

}
输入:
输出你的祝福或者愿望给树洞,回复“0”结束说话
aa
0

输出:
aa  树洞准奏

但是报错java.lang.StringIndexOutOfBoundsException: String index out of range: -1
可能跟客户端判断输入信息有关

多线程案例尝试通信

客戶端:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

/**
 * 客户端需要两个流,一个输出流给服务器端传送数据,一个输入流读取服务器端的反馈(用线程类写)
 * 
 * @author Aoman_Hao
 */
public class CRClientDemo {

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

        //建立socket对象
        Socket s = new Socket("192.168.0.111", 5000);

        //输入流,读取服务器的数据用新建线程类 new Thread(new target)
        new Thread(new ClientThread(s)).start();

        //输出流,数据写给服务器
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

        //读键盘录入的数据 
        BufferedReader br =  new BufferedReader(new InputStreamReader(System.in));
        System.out.println("输入录入数据:");
        //遍历
        String line = null;
        while((line = br.readLine())!=null){

            //数据输出到流中
            bw.write(line);
            bw.flush();
        }
        bw.close();
        s.close();
    }
}

客戶端綫程類
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

/**
 * @author Aoman_Hao
 */
public class ClientThread implements Runnable{

    private Socket s;
    BufferedReader br = null ;
    public ClientThread() {
        super();
    }

    public ClientThread(Socket s) throws IOException{
        this.s = s;
    }


    @Override
    public void run() {
        String line = null;
        try {
            //构造输入流
            BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); 
            //获取流中的数据
            while((line = br.readLine())!=null){
                System.out.println("服务器回馈:"+line);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

服务器端:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @author Aoman_Hao
 */
public class CRServerDemo {

    public static void main(String[] args) throws IOException {
        // 建立socket对象
        ServerSocket ss = new ServerSocket(5000);

        // 建立监听对象
        Socket s = ss.accept();

        // 输入流用线程类
        Thread T_Server = new Thread(new ServerThread(s), "服务器端读数据");
        T_Server.start(); 
    }

}

服务器端线程类:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

/**
 * @author Aoman_Hao
 */
public class ServerThread implements Runnable{

    private Socket s;
//  private BufferedReader br = null ;
//  private BufferedWriter bw = null ;

    public ServerThread() {
        super();
    }

    //有参构造
    public ServerThread(Socket s) throws IOException{
        this.s = s;

    }

    @Override
    public void run() {

        String line = null;
        try {
            //读取流中客户端发来的数据
            BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
            // 输出流,反馈给客户端
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
                    s.getOutputStream()));
            while((line = br.readLine()) != null){
                System.out.println("客户端数据:"+line+"\r\n");
                bw.write(line+"\t录入");
                bw.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

客户端读取文件,服务器端显示数据

客户端:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;

/**
 * @author Aoman_Hao
 */
public class JCClientDemo {

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

        //创建socket对象
        Socket s = new Socket("192.168.0.111",5000);

        //文件字节流缓冲流
        BufferedReader br = new BufferedReader(new FileReader("D:\\Java\\JavaTest\\Aoman_3.txt"));

        //socket的输出流
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

        //遍历  不能用byte
        String line = null;
        while((line = br.readLine())!= null){

            //写在输出流中
            bw.write(line);
            bw.flush();

    }
        bw.close();
        s.close();
}}

服务器端:

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 
 * 需求:客户端一个文本文件,服务器端将客户端文本文件中的内容展示到控制台上
 * @author Aoman_Hao
 */
public class JCServerDemo {

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

        //创建socket对象
        ServerSocket ss = new ServerSocket(5000);

        //监视socket对象数据
        Socket s = ss.accept();

        //输入流
        BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));

        //展示在控制台
        String line = null;
        while((line = br.readLine()) != null){

            System.out.println(line);
        }


    }

}