Java网络编程

一、概念

IP地址:确定计算机在网络上的哪个节点

端口号:确定app和哪个服务器对接,区分计算机上的软件,相当于一个房门。ex: QQ - 对接QQ的sever。2个字节,范围 0 - 65536

  • 同一协议下,端口号不能重复
  • 1024以下的端口不要使用,0-1024是给某些厂商预留的端口。ex: 80--> http , 21 ---> ftp

确定了地址(计算机),确定了端口(软件),接下来还需要确定资源怎么进来。 

资源定位符: URL (既有资源又有定位),  URI (资源) 

数据传输: 比如确定用什么语言啊之类的,所以需要有协议

  • TCP协议(transfer control protocol)(必须先连接,类似于打电话),需要三次握手,所以安全,但是效率低下  / 面向连接
  • UDP协议 (user datagram protocol)(类似于发短信,只管往外发),不需要先连接,所以不安全,但效率高  /非面向连接

传输:先封装,后拆封,这样就涉及到了网络分层

网络分层

  1. 应用层
  2. 传输层(TCP/UDP)
  3. 网络层(IP)
  4. 物理 + 数据链路层

涉及到的java类

  1. IP:InetAddress ,  端口:InetSocketAddress
  2. URL
  3. TCP: ServerSocket, Socket
  4. UDP: DatagramSocket, DatagramPacket

 

二、InetAddress 和 InetSocketAddress

InetAddress: 封装了IP地址和DNS(域名解析),但没有端口。 域名解析: 比如把 223.87.1.58解析为www.163.com  (你记不住有的没的一串数字的) 

InetSocketAddress: 包含端口

 

InetAddress方法:

  • getHostAddress()  //返回IP地址
  • getHostName()  //返回域名,本机为计算机名
  • getLocalHost()
  • getByName(“IP地址 / 或者域名”)  

 

InetSocketAddress封装端口 

1、创建对象

2、方法

  • getAddress()
  • getHostName()
  • getPort()

 

三、URL, 网络爬虫原理

URL/URI,统一资源定位符,有4部分组成:

  1. 协议
  2. 存放资源的主机域名
  3. 端口
  4. 资源文件名

URL (String spec)   //绝对路径构建

URL(URL context, String spec)  //相对路劲构建

public class URLDemo {
    public static void main(String[] args) throws MalformedURLException {
        //绝对路径
        URL url = new URL("http://www.baidu.com:80/index.html#aa?uname=maxmaxmax");

        //方法
        System.out.println("协议: " + url.getProtocol() );
        System.out.println("域名: " + url.getHost() );
        System.out.println("端口: " + url.getPort() );
        System.out.println("资源: " + url.getFile() );
        System.out.println("相对路径: " + url.getPath() );
        System.out.println("锚点: " + url.getRef() );
        System.out.println("参数 " + url.getQuery() );    //?参数:存在锚点,返回Null,不存在,返回正确


        //相对路径
        URL url2 = new URL("http://www.baidu.com:80/a/");
        URL url3= new URL(url2, "b.txt");

    }
}
/***
 * 获取资源:源代码 (通过流)
 */

public class URLDemo2 {
    public static void main(String[] args) throws IOException {
        URL url = new URL("http://www.baidu.com"); //主页,默认资源

        //获取资源,右键百度首页 - 查看页面源代码 - 这里面的代码主要包含:html, css, js
        

     //使用流获取源代码      BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream(),"utf-8")); //把读取到的源代码输出成一个html文件 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("baidu.html"),"utf-8")); String msg = null; while ((msg = br.readLine())!= null){ bw.append(msg); bw.newLine(); } bw.flush(); bw.close(); br.close(); } //以上其实就是网络爬虫的第一步,获取源代码,再用正则表达式分析源码,达到下载目标数据的目的,网络爬虫就是下载数据 }

 

四、UDP编程

创建服务器和客户端,发送数据

/**
 * 服务端
 * 1、创建服务器 + 端口
 * 2、准备接收容器
 * 3、封装成包
 * 4、接收数据
 * 5、分析数据
 */
public class UDP_TestDemo_MyServer {

    public static void main(String[] args) throws IOException {
        // 1、创建服务器 + 端口
        DatagramSocket server = new DatagramSocket(8888);
        // 2、准备接收容器
        byte [] container = new byte[1024];
        // 3、封装成包
        DatagramPacket packet = new DatagramPacket(container, container.length);
        // 4、接收数据
        server.receive(packet);
        // 5、分析数据
        byte[] data = packet.getData();
        int len = packet.getLength();
        System.out.println(new String(data, 0, len));
        // 6、释放资源
        server.close();
    }
}
/**
 * 客户端
 * 1、创建客户端 + 端口
 * 2、准备数据
 * 3、打包 (数据发往的地点和端口)
 * 4、发送
 * 5、释放
 */
public class UDP_TestDemo_MyClient {
    public static void main(String[] args) throws IOException {
        // 1、创建客户端 + 端口
        DatagramSocket client = new DatagramSocket(6666);
        // 2、准备数据
        String msg = "UDP编程";
        byte[] data = msg.getBytes();
        // 3、 打包 (数据发往的地点和端口)
        DatagramPacket packet = new DatagramPacket(data, data.length, new InetSocketAddress("LocalHost", 8888));
        // 4、发送
        client.send(packet);
        // 5、释放
        client.close();
    }
}

 

五、TCP编程,Socket通信

区别于UDP, TCP需要先握手(确认连接),再传输数据

public class TCP_TestDemo_Server {
    public static void main(String[] args) throws IOException {
        // 1、创建服务器  + 指定端口
        ServerSocket server = new ServerSocket(8888);
        // 2、接收客户端连接,阻塞式
        Socket socket = server.accept();
        System.out.println("一个客户端建立连接");
        // 3、发送数据
        String msg = "欢迎使用";
        //输出流
        BufferedWriter bw = new BufferedWriter(
                new OutputStreamWriter(
                        socket.getOutputStream()));

        bw.write(msg);
        bw.newLine();
        bw.flush();
    }
}
public class TCP_TestDemo_Client {
    public static void main(String[] args) throws IOException {
        // 1、创建客户端,必须指定服务器 + 端口,此时就在连接
        Socket client = new Socket("localhost", 8888);
        // 2、接受数据
        BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
        String echo = br.readLine(); //看服务端的代码,有一个bw.newine(),因为br是逐行读取,不写一个newLine()的话,会读不到数据
        System.out.println(echo);

    }
}

 

上面这段代码,是一次简单的服务器和客户端的交互,只能执行一次(先运行服务端,再运行客户端),实际中,客户端可以和服务器多次交互,可以参考聊天室项目的代码。

posted on 2018-09-19 23:36  TheExile  阅读(176)  评论(0)    收藏  举报

导航