java网络编程(详细)

一、 IP

package com.zlf.network;

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

public class TestInetAddress {
    public static void main(String[] args) {
        try {
//            查询本机地址
            InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
            System.out.println(inetAddress1);
            InetAddress inetAddress2 = InetAddress.getByName("localhost");
            System.out.println(inetAddress2);
            InetAddress inetAddress3 = InetAddress.getLocalHost();
            System.out.println(inetAddress3);
//            查询网站ip地址
            InetAddress inetAddress5 = InetAddress.getByName("www.baidu.com");
            System.out.println(inetAddress5);


            System.out.println("*****************常用方法**************");
//            常用方法
            System.out.println(inetAddress5.getAddress());//
            System.out.println(inetAddress5.getCanonicalHostName());//获取规范的名字
            System.out.println(inetAddress5.getHostAddress()); //获取ip
            System.out.println(inetAddress5.getHostName());//域名或者自己电脑的名字

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

输出结果

/127.0.0.1
localhost/127.0.0.1
DESKTOP-UTDKEAA/192.168.184.1
www.baidu.com/39.156.66.14
*****************常用方法**************
[B@6e8cf4c6
39.156.66.14
39.156.66.14
www.baidu.com

Process finished with exit code 0

二、端口

端口被规定:0~65535
端口分类

  1. 共有端口:0~1023
      HTTP:80
      HTTPS:443
      FTP:21
      Telent:23
  2. 程序注册端口:1024~49151
      Tomcat:8080
      MySQL:3306
      Oracle:1521

DOS命令查看端口

  • 查看所有端口:netstat -ano
  • 查看指定端口:netstat -ano|findstr "端口号"
  • 查看指定端口号进程:tasklist|findstr "端口号"

代码示例

package com.zlf.network;

import java.net.InetSocketAddress;

public class TestInetSocketAddress {
//    说到端口需要引入一个类:InetSocketAddress
//    此类实现IP套字节地址(IP+端口号)

    /*
    *构造方法
    * ## 构造方法摘要
        InetSocketAddress(InetAddress addr, int port)
        根据IP地址和端口号创建套接字地址
        InetSocketAddress(int port)
        创建套接字地址,其中ip地址为通配符地址,端口号为指定值
        InetSocketAddress(String hostname,int port)
        根据主机名和端口号创建套接字地址
    * */

    public static void main(String[] args) {
        InetSocketAddress localhost = new InetSocketAddress("localhost", 8080);


//        常用方法
        System.out.println(localhost.getAddress());//获取InetAddress
        System.out.println(localhost.getHostName());//获取域名
        System.out.println(localhost.getPort());//获取端口
    }
}

输出结果

localhost/127.0.0.1
localhost
8080

三、通信协议

TCP/IP的三次握手

  • 第一次握手:客户端将标志位SYN置为1,随机产生一个值seq=J,并将改数据包发送给服务器端,客户端进入SYN_SENT状态等待服务器确认
  • 第二次握手:服务器收到数据包后,由标志位SYN=1指导客户端请求建立连接,服务器将标志位SYN和ACK都置为1,ack=J+!,随机产生一个值seq=K,并将该数据包发送给客户端以确认连接请求,服务器进入SYN_REVD状态
  • 第三次握手:客户端收到消息后,检查ack是否为J+1,ACK是否为1,如果正确将标志位ACK置为1,ack=k+1,并将该数据包发送给服务端,服务器检查ack是否为 K+1,ACK是否为1,如果正确建立连接,两端进入ESTABLISH状态,完成三次握手,随后两端开始传输数据
    四次挥手(中断连接端可以是客户端,也可以是服务器端。)
  • 第一次挥手:客户端发送一个FIN=M,用来关闭客户端到服务端的数据传送,客户端进入FIN_WAIT_1状态。意思是说:“我客户端没有数据要发给你了,但是如果你服务器还有数据没有完成发送,则不必着急关闭连接,可以继续发送数据”
  • 第二次挥手:服务器收到FIN后 ,发送ack=M+1,告诉客户端,你的请求我已经收到了,但是我还没准备好,请你继续等待我的消息,这个时候客户端进入FIN_WAIT_2状态,继续等待服务器的FIN报文
  • 第三次挥手:当服务器确定数据已经完成发送,则向客户端发送FIN=N报文,告诉客户端,好了,我这边数据发完了,准备好关闭连接,服务器进入LAST_ACK状态。
  • 第四次挥手:客户端收到FIN=N报文,就知道可以关闭连接了,但是他还是不相信网络,怕服务器不知道要关闭,所以发送ack=N+1后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。服务器收到ACK后,就知道可以断开连接了,客户端等待了2MSL后依然没有收到回复,则证明服务器端已经正常关闭了,最终客户端完成关闭

四、TCP通信

  • 在java中,提供了两个类用于实现TCP通信程序

    1. 客户端:java.net.Socket类表示,创建socket对象,向服务端发出连接请求,服务端响应请求,两者建立连接开始通信
    2. 服务端:java.net.ServerSocket类表示,创建ServerSocket对象,相当于开启了一个服务,并等待客户端得连接
  • 客户端代码实现

package com.zlf.network;

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

//客户端
public class TCPClientDemo01 {
/*
* `Socket`类:该类试下了客户端得套接字
构造方法摘要
+ public Socket(String host,int port):创建套接字对象并将其连接到指定主机上的指定端口号。如果指定的host是null ,则相当于指定地址为回送地址。
	回送地址(127.x.x.x) 是本机回送地址(Loopback Address),主要用于网络软件测试以及本地机进程间通信,无论什么程序,一旦使用回送地址发送数据,立即返回,不进行任何网络传输。

常用方法摘要
+ public InputStream getInputStream():返回此套接字得输入流
	1. 如果此Socket具有相关联得通道,则生成InputStream得所有操作也关联该通道
	2. 关闭生成得InputStream也将关闭相关得Socket
+ public OutputStream getOutputStream():返回此套接字得输出流
	1. 如果此Scoket具有相关联的通道,则生成的OutputStream 的所有操作也关联该通道。
	2. 关闭生成的OutputStream也将关闭相关的Socket。
+ public void close():关闭此套接字
	1. 一旦一个socket被关闭,它不可再使用
	2. 关闭此socket也将关闭相关得InputStream和OutputStream
+ public void shutdownOutput():禁用此套接字得输出流
	1. 任何先前写出得数据将被发送,随后终止输出流*/
    public static void main(String[] args) {
        Socket socket = null;
        OutputStream os = null;

        try {
            InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
            socket = new Socket(inetAddress,8090);
            os = socket.getOutputStream();
            os.write("你好,我是客户端".getBytes());


        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(os != null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

  • 服务端代码实现
package com.zlf.network;

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

//服务端
public class TCPServerDemo01 {


    /*
    * 分析服务端内容
    * 1. 需要一个地址*/
    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        InputStream is = null;
        Socket socket = null;
        ByteArrayOutputStream baos = null;

        try {
            serverSocket = new ServerSocket(8090);
            socket = serverSocket.accept();
            is =  socket.getInputStream();

            baos = new ByteArrayOutputStream();
            int len = 0;
            byte[] bytes = new byte[1024];
            while((len=is.read(bytes))!=-1){
                baos.write(bytes,0,len);
            }

            System.out.println("收到了来自客户端得"+socket.getInetAddress().getHostName()+"的消息"+baos.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(serverSocket!=null){
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(socket!=null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(is!=null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(baos!=null){
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

 }

五、UDP网络编程

从技术意义上来讲,只有TCP才会分Server和Client。对于UDP来说,从严格意义上来讲,并没有所谓的Server和Client。
java.net包给我们提供了两个类DatagramSocket(此类表示用于发送和接收数据报的套接字)和DatagramPacket(该类表示数据报的数据包。 )

发送数据端

package com.zlf.network;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class UDPClient {
    public static void main(String[] args) throws Exception {
//        建立一个Socket
        DatagramSocket datagramSocket = new DatagramSocket();
//        建一个包
        String msg = "你好啊,服务器,UDP发送";

//        发送给谁
        InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
        int port = 9090;
        DatagramPacket packet = new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,inetAddress,port);

//        发送包
        datagramSocket.send(packet);

//        关闭流
        datagramSocket.close();
    }
}

接收数据端

package com.zlf.network;

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

public class UDPServer {
    public static void main(String[] args) throws Exception{
//        开放端口
        DatagramSocket socket = new DatagramSocket(9090);
       byte[] buffer = new byte[1024];
        DatagramPacket datagramPacket = new DatagramPacket(buffer,0,buffer.length);

//        接收数据包
        socket.receive(datagramPacket);
        System.out.println(datagramPacket.getAddress().getHostName());
        System.out.println(new String(datagramPacket.getData(),0,datagramPacket.getLength()));
//        关闭连接
        socket.close();
    }
}

六、UDP实现消息传输

发送方

package com.zlf.network.chat;

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

public class Send {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket();

        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        String data = bufferedReader.readLine();
        System.out.println(data);
       while(true){
           DatagramPacket packet = new DatagramPacket(data.getBytes(),0,data.getBytes().length, InetAddress.getByName("127.0.0.1"),8000);
           socket.send(packet);
           data = bufferedReader.readLine();
       }

    }
}

接收方

package com.zlf.network.chat;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class Receive {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(8000);


        while (true) {
            byte[] buffer = new byte[1024];
            DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);
            socket.receive(packet);
            String receiveDta = new String(packet.getData(),0, packet.getLength());
            System.out.println(receiveDta);

        }




    }
}

七、URL下载网络资源

java.net包下

构造方法摘要

  • URL(String spec)根据String表示形式创建URL对象。
  • URL(String protocol,String host,int port,String file)根据指定协议名,主机名,端口号和文件名创建URL对象
  • URL(String protocol,String host,String file)根据指定的协议名、主机名、和文件名创建URL

常用方法

  • String getProtocol()获取此URL的协议名称
  • String getHost() 获取URL的主机名
  • String getPort()获取此url的端口号
  • String getPath() 获取此 URL 的文件路径。
  • String getFile()获取此 URL 的文件名。
  • String getQuery()获取此 URL的查询部分。
  • URLConnection openConnection() 返回一个URLConnection实例,表示与URL引用的远程对象的URL 。
  • URLConnection类中又有一个方法:
    InputStream getInputStream()返回从此打开的连接读取的输入流。

代码示例

package com.zlf.network.URL;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class TestURL {
    /*
    * 常用方法
    + String getProtocol() 获取此URL的协议名称
    + String getHost() 获取URL的主机名
    + String getPort() 获取此url的端口号
    + String getPath() 获取此 URL 的文件路径。
    + String getFile()获取此 URL 的文件名。
    + String getQuery()获取此 URL的查询部分。
    + URLConnection openConnection() 返回一个URLConnection实例,表示与URL引用的远程对象的URL 。
    + URLConnection类中又有一个方法:
        InputStream getInputStream() 返回从此打开的连接读取的输入流。
    * */
    public static void main(String[] args) throws IOException {
        URL url = new URL("http://localhost:8080/zhoulinfeng/%E7%BA%BF%E6%9D%A1.jpg");
        System.out.println(url.getProtocol());
        System.out.println(url.getHost());
        System.out.println(url.getHost());
        System.out.println(url.getPort());
        System.out.println(url.getPath());
        System.out.println(url.getFile());
        System.out.println(url.getQuery());

        System.out.println("+++++++++++++++++++++++++");


        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
        InputStream inputStream = httpURLConnection.getInputStream();

        FileOutputStream fops = new FileOutputStream(new File("C:\\Users\\18317\\Desktop\\线条.jpg"));
        byte[] buffer = new byte[1024];
        int len;
        while((len=inputStream.read(buffer))!=-1){
            fops.write(buffer,0,len);
        }
        httpURLConnection.disconnect();
        inputStream.close();
        fops.close();


    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值