zoukankan      html  css  js  c++  java
  • JAVA基础-网络编程

    类 InetAddress

    此类表示互联网协议 (IP) 地址。

    IP 地址是 IP 使用的 32 位或 128 位无符号数字,它是一种低级协议,UDP 和 TCP 协议都是在它的基础上构建的。IP 地址的体系结构是由 RFC 790:Assigned

    Numbers RFC 1918:Address Allocation for Private InternetsRFC 2365:Administratively Scoped

    IP MulticastRFC 2373:IP Version 6 Addressing

    Architecture 定义的。InetAddress 的实例包含 IP

    地址,还可能包含相应的主机名(取决于它是否用主机名构造或者是否已执行反向主机名解析)。

    网络编程三要素:

    A:IP地址

    B:端口

    C:协议

    public class InetAddressDemo {
    public static void main(String[] args) throws UnknownHostException {
    // public static InetAddress getByName(String host)
    // InetAddress address = InetAddress.getByName("liuyi");
    // InetAddress address = InetAddress.getByName("192.168.12.92");
    InetAddress address1 = InetAddress.getByName("172.16.102.58");
    InetAddress[] address2 = InetAddress.getAllByName("172.16.102.58");
    // 获取两个东西:主机名,IP地址
    // public String getHostName()
    // public String getHostAddress()
    String name1 = address1.getHostName();
    String ip1 = address1.getHostAddress();
    
    for (InetAddress inetAddress : address2) {
    System.out.println(inetAddress);
    }
    
    System.out.println(name1 + "---" + ip1);
    }
    }

    IP地址:

    网络中计算机的唯一标识。

    计算机只能识别二进制的数据,所以我们的IP地址应该是一个二进制的数据。

    但是呢,我们配置的IP地址确不是二进制的,为什么呢?

    IP:192.168.1.100

    换算:11000000 10101000 00000001 01100100

    假如真是:11000000 10101000 00000001 01100100的话。

    我们如果每次再上课的时候要配置该IP地址,记忆起来就比较的麻烦。

    所以,为了方便表示IP地址,我们就把IP地址的每一个字节上的数据换算成十进制,然后用.分开来表示:

    "点分十进制"

    IP地址的组成:网络号段+主机号段

    A类:第一号段为网络号段+后三段的主机号段

    一个网络号:256*256*256 = 16777216

    B类:前二号段为网络号段+后二段的主机号段

    一个网络号:256*256 = 65536

    C类:前三号段为网络号段+后一段的主机号段

    一个网络号:256

    IP地址的分类:

    A类 1.0.0.1---127.255.255.254 (1)10.X.X.X是私有地址(私有地址就是在互联网上不使用,而被用在局域网络中的地址) (2)127.X.X.X是保留地址,用做循环测试用的。

    B类 128.0.0.1---191.255.255.254 172.16.0.0---172.31.255.255是私有地址。169.254.X.X是保留地址。

    C类 192.0.0.1---223.255.255.254 192.168.X.X是私有地址

    D类 224.0.0.1---239.255.255.254

    E类 240.0.0.1---247.255.255.254

    两个DOS命令:

    ipconfig 查看本机ip地址

    ping 后面跟ip地址。测试本机与指定的ip地址间的通信是否有问题

    特殊的IP地址:

    127.0.0.1 回环地址(表示本机)

    x.x.x.255 广播地址

    x.x.x.0 网络地址

    端口号:

    正在运行的程序的标识。

    有效端口:0~65535,其中0~1024系统使用或保留端口。

    协议:

    通信的规则

    UDP:

    把数据打包

    数据有限制

    不建立连接

    速度快

    不可靠

    TCP:

    建立连接通道

    数据无限制

    速度慢

    可靠

    举例:

    UDP:发短信

    TCP:打电话

    Scoket

    --java.net

    -- --DatagramSocket

    此类表示用来发送和接收数据报包的套接字。

    -- --DatagramPacket

    此类表示数据报包。

    数据报包用来实现无连接包投递服务。每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。不对包投递做出保证。

    UDP协议发送数据:

    A:创建发送端Socket对象

    B:创建数据,并把数据打包

    C:调用Socket对象的发送方法发送数据包

    D:释放资源

     public class SendDemo {
    public static void main(String[] args) throws IOException {
    // 创建发送端Socket对象
    // DatagramSocket()
    DatagramSocket ds = new DatagramSocket();
    
    // 创建数据,并把数据打包
    // DatagramPacket(byte[] buf, int length, InetAddress address, int port)
    // 创建数据
    byte[] bys = "hello,udp,我来了".getBytes();
    // 长度
    int length = bys.length;
    // IP地址对象
    InetAddress address = InetAddress.getByName("172.16.102.58");
    // 端口
    int port = 10010;
    DatagramPacket dp = new DatagramPacket(bys, length, address, port);
    
    // 调用Socket对象的发送方法发送数据包
    // public void send(DatagramPacket p)
    ds.send(dp);
    
    // 释放资源
    ds.close();
    }
    }

    UDP协议接收数据:

    A:创建接收端Socket对象

    B:创建一个数据包(接收容器)

    C:调用Socket对象的接收方法接收数据

    D:解析数据包,并显示在控制台

    E:释放资源

     public class ReceiveDemo {
    public static void main(String[] args) throws IOException {
    // 创建接收端Socket对象
    // DatagramSocket(int port)
    DatagramSocket ds = new DatagramSocket(10010);
    
    // 创建一个数据包(接收容器)
    // DatagramPacket(byte[] buf, int length)
    byte[] bys = new byte[1024];
    int length = bys.length;
    DatagramPacket dp = new DatagramPacket(bys, length);
    
    // 调用Socket对象的接收方法接收数据
    // public void receive(DatagramPacket p)
    ds.receive(dp); // 阻塞式
    
    // 解析数据包,并显示在控制台  
    // 获取对方的ip
    // public InetAddress getAddress()
    InetAddress address = dp.getAddress();
    String ip = address.getHostAddress();
    // public byte[] getData():获取数据缓冲区
    // public int getLength():获取数据的实际长度
    byte[] bys2 = dp.getData();
    int len = dp.getLength();
    String s = new String(bys2, 0, len);
    System.out.println(ip + "传递的数据是:" + s);
    
    // 释放资源
    ds.close();
    }
    }

    TCP协议发送数据:

    A:创建发送端的Socket对象

    这一步如果成功,就说明连接已经建立成功了。

    B:获取输出流,写数据

    C:释放资源

    TCP协议接收数据:

    A:创建接收端的Socket对象

    B:监听客户端连接。返回一个对应的Socket对象

    C:获取输入流,读取数据显示在控制台

    D:释放资源

     public class ClientDemo {
    public static void main(String[] args) throws IOException {
    // 创建Socket对象
    Socket s = new Socket("192.168.12.92", 34567);
    
    // 封装文本文件
    BufferedReader br = new BufferedReader(new FileReader(
    "InetAddressDemo.java"));
    // 封装通道内的流
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
    s.getOutputStream()));
    
    String line = null;
    while ((line = br.readLine()) != null) {
    bw.write(line);
    bw.newLine();
    bw.flush();
    }
    
    br.close();
    s.close();
    }
    }

    -- --ServerSocket

    此类实现服务器套接字。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。

    服务器套接字的实际工作由 SocketImpl

    类的实例执行。应用程序可以更改创建套接字实现的套接字工厂来配置它自身,从而创建适合本地防火墙的套接字。

    public class ServerDemo {
    public static void main(String[] args) throws IOException {
    // 创建服务器Socket对象
    ServerSocket ss = new ServerSocket(34567);
    
    // 监听客户端连接
    Socket s = ss.accept();
    
    // 封装通道内的流
    BufferedReader br = new BufferedReader(new InputStreamReader(
    s.getInputStream()));
    
    String line = null;
    while ((line = br.readLine()) != null) {
    System.out.println(line);
    }
    
    
    s.close();
    }
    }

    利用Socket进行网络通信开发

    在网络编程中,接触到最多的就是利用Socket进行网络通信开发。在Java中主要是以下三种实现方式BIO、NIO、AIO。

    关于这三个概念的辨析以前一直都是好像懂,但是表达的不是很清楚,下面做个总结完全辨析清楚。

    1. BIO方式

    首先我用一个较为通俗的语言来说明:

    BIO 就是阻塞IO,每个TCP连接进来服务端都需要创建一个线程来建立连接并进行消息的处理。如果中间发生了阻塞(比如建立连接、读数据、写数据时发生阻碍),线程也会发生阻塞,并发情况下,N个连接需要N个线程来处理。

    这种方式的缺点就是:并发情况下效率很低

    2. NIO方式

    NIO是JDK1.4提出的,还是先用一段通俗的话来说明NIO的工作原理:

    NIO 也就是非阻塞IO,是基于事件驱动的思想(Reactor线程模型)。对比与BIO来说,NIO使用一个线程来管理所有的Socket 通道,也就是基于Selector机制,当查询到事件时(连接、接受连接、读、写),就会转发给不同的处理线程(handler)。

    3. AIO方式

    AIO是JDK1.7提出的,也就是异步IO。AIO采用的是Proactor模式。我们首先应该辨析的是AIO和NIO的区别:

    (1)NIO的通知是发生在Handler之前;

    (2)AIO的通知是发生在读写等处理之后的回调,有通知时表示相关操作已经结束了。

    AIO在进行读写操作时,只需要调用相应的read/write方法,并传入CompletionHandler(动作完成时处理器),在动作完成后会调用CompletionHandler。 NIO的通知是发生在动作之前,是在可读可写的时候,Selector发现了这些事件后就通知并调用Handler处理,

    下面给出Proactor模式的工作流程图:

  • 相关阅读:
    iphone 使用委托(delegate)在不同的窗口之间传递数据
    创建单键模式的类
    读入Plist文件中的信息
    C#读取Excel,取值为空的解决办法!
    ORACLE 常见的数据类型
    ArcGISServer 将内网地图服务映射修改外网可以访问的地图服务
    C#中获取当前路径的几种方法
    sql server2005登录出错问题(转载)
    (转载)服务器控件的生命周期
    ORACLE 中ROWNUM用法总结(转载)
  • 原文地址:https://www.cnblogs.com/GitBoy/p/11093767.html
Copyright © 2011-2022 走看看