Java网络编程

Java网络编程,第1张

Java网络编程
网络编程的三要素:
    1、IP地址
        网络中计算机的唯一标识。

        但是我们计算机只能识别二进制的数据,所以我们想着IP地址在计算机存储的格式
        应该也是一个二进制。
        查看windows中ip地址:win+R ,输入cmd,输入ipconfig回车

        IP: 192.168.3.170
        换算成二进制:11000000.10101000.00000011.10101010
        实际上存储的时候:11000000101010000000001110101010,但是呢,这样的形式,
        在学习的时候,难免要去配置地址等,记忆等等涉及到地址 *** 作的时候,表示起来会很麻烦。
        所以,为了更方便的表示ip地址,我们就把ip地址上的每一个字节的数据换算成十进制,然后再在
        字节与字节之间用.分割表示,而这样的表示法:叫做点分十进制表示法。

        IP地址的组成:网络号段 + 主机号段
        IP地址的分类:
            A类:第一个号段为网络号段 + 后面三个号段都为主机号段
                可以有:256 * 256 * 256 这么多台计算机

            B类:前两个号段为网络号段 + 后面两个为主机号段
                可以有:256 * 256 这么多台计算机

            C类:前三个号段为网络号段 + 最后一个为主机号段
                可以有:256台计算机
            D类:224.0.0.1---239.255.255.254
            E类:240.0.0.1---247.255.255.254

           特殊的IP地址
               1、localhost == 本机 == 127.0.0.1
                   127.0.01 回环地址,可用于测试本机的网络是否有问题,ping 127.0.0.1

               2、广播地址:
                   x.x.x.255

               3、网络地址:
                   x.x.x.0

           三个DOS命令:
               1、查看windows中ip地址:win+R ,输入cmd,输入ipconfig回车
               2、测试网络是否联通
                   ping + IP地址/hosts名
    2、端口号
        物理端口 网卡口
        逻辑端口 我们指的就是逻辑端口
           A:每个网络程序都会至少有一个逻辑端口
           B:用于标识进程的逻辑地址,不同进程的标识
           C:有效端口:0~65535,其中0~1024系统使用或保留端口。
           通过netstat  -ano可以查看端口号

    3、协议
        UDP协议(发短信,飞鸽传书)
        TCP协议(建立连接,极域)
            三次握手四次挥手

InetAddress
为了方便我们获取IP地址,java提供了一个类InetAddress供我们使用

查看API文档我们知道:

  • public class InetAddress
    extends Object
    implements Serializable
    此类表示Internet协议(IP)地址

    IP地址是由IP使用的32位或128位无符号数字,构建UDP和TCP协议的低级协议。 IP地址结构由定义RFC 790: Assigned Numbers , RFC 1918: Address Allocation for Private Internets , RFC 2365: Administratively Scoped IP Multicast和RFC 2373: IP Version 6 Addressing Architecture 。 InetAddress的一个实例由一个IP地址和可能的相应主机名组成(取决于它是用主机名构造还是已经完成了反向主机名解析)。

    地址类型
    unicastAn identifier for a single interface. A packet sent to a unicast address is delivered to the interface identified by that address.

    The Unspecified Address -- Also called anylocal or wildcard address. It must never be assigned to any node. It indicates the absence of an address. One example of its use is as the target of bind, which allows a server to accept a client connection on any interface, in case the server host has multiple interfaces.

    The unspecified address must not be used as the destination address of an IP packet.

    The Loopback Addresses -- This is the address assigned to the loopback interface. Anything sent to this IP address loops around and becomes IP input on the local host. This address is often used when testing a client.

    multicastAn identifier for a set of interfaces (typically belonging to different nodes). A packet sent to a multicast address is delivered to all interfaces identified by that address.

    IP地址范围

    链路本地地址被设计为用于单个链路上的寻址,例如自动地址配置,邻居发现或当没有路由器存在时。

    站点本地地址被设计为用于在站点内部寻址,而不需要全局前缀。

    全球地址在互联网上是独一无二的。

    IP地址的文字表示

    IP地址的文本表示是特定于地址的。

    IPv4地址格式请参考Inet4Address#format ; IPv6地址格式请参考Inet6Address#format 。

    有一个couple of System Properties影响如何使用IPv4和IPv6地址。

    主机名解析

    主机名称到IP地址解析是通过使用本地机器配置信息和网络命名服务(如域名系统(DNS)和网络信息服务(NIS))的组合来实现的。 所使用的特定命名服务是默认配置的本地机器。 对于任何主机名,返回其对应的IP地址。

    反向名称解析意味着对于任何IP地址,返回与IP地址关联的主机。

    InetAddress类提供了将主机名解析为其IP地址的方法,反之亦然。

    InetAddress缓存

    InetAddress类具有高速缓存以存储成功以及不成功的主机名解析。

    默认情况下,安装安全管理器时,为了防止DNS欺骗攻击,主机名正确解决方案的结果将永久缓存。 当没有安装安全管理器时,默认的行为是缓存条目以获得有限的(实现依赖的)时间段。 不成功的主机名解析的结果被缓存很短的时间(10秒),以提高性能。

    如果不需要默认行为,则可以将Java安全属性设置为不同的生存时间(TTL)值进行正缓存。 同样,系统管理员可以在需要时配置不同的缓存缓存TTL值。

    两个Java安全属性控制用于正负主机名解析缓存的TTL值:

    networkaddress.cache.ttlIndicates the caching policy for successful name lookups from the name service. The value is specified as as integer to indicate the number of seconds to cache the successful lookup. The default setting is to cache for an implementation specific period of time.

    A value of -1 indicates "cache forever".

    networkaddress.cache.negative.ttl (default: 10)Indicates the caching policy for un-successful name lookups from the name service. The value is specified as as integer to indicate the number of seconds to cache the failure for un-successful lookups.

    A value of 0 indicates "never cache". A value of -1 indicates "cache forever".

参考代码:

import java.net.InetAddress;

public class InetAddressDemo {
    public static void main(String[] args) throws Exception {
        //static InetAddress getByName(String host)
        //确定主机名称的IP地址。
        InetAddress address = InetAddress.getByName("192.168.3.145");
        System.out.println(address);

        //String getHostName()
        //获取此IP地址的主机名。
        String hostName = address.getHostName();
        System.out.println(hostName);

        //String getHostAddress()
        //返回文本显示中的IP地址字符串。
        String hostAddress = address.getHostAddress();
        System.out.println(hostAddress);
    }
}

运行结果:

/192.168.3.145
DESKTOP-G2RLTSN
192.168.3.145


UDP协议
UDP协议接收数据:
    1、创建接收端的Socket对象
    2、创建一个数据包(用来数据的容器)
    3、调用Socket对象方法接收数据
    4、解析数据包,显示在控制台上
    5、释放资源
UDP协议发送数据:
    1、创建发送端的Socket对象
    2、创建数据,将数据打包
    3、调用Socket对象中的一个方法,将数据包发出去
    4、释放资源,关闭Socket对象
参考代码
SendDemo:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;


public class SendDemo2 {
    public static void main(String[] args) throws Exception {
        //创建发送端的Socket对象
        DatagramSocket ds = new DatagramSocket();

        //封装键盘录入的数据
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        String line = null;
        while ((line = br.readLine())!=null){
            if("886".equals(line)){
                break;
            }

            //如果输入的不是886将数据打包发送
            DatagramPacket dp = new DatagramPacket(line.getBytes(), line.getBytes().length,
                    InetAddress.getByName("192.168.3.145"), 12345);

            //调用Socket对象发送数据包
            ds.send(dp);
        }

        //释放资源
        ds.close();



    }
}

 ReceiveDemo:

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


    public class ReceiveDemo2 {
    public static void main(String[] args) throws Exception {
        //创建接收端的Socket对象
        DatagramSocket ds = new DatagramSocket(12345);

        while (true){
            //创建接收数据包
            byte[] bytes = new byte[1024];
            DatagramPacket dp = new DatagramPacket(bytes, bytes.length);

            //调用Socket对象接收数据包的方法
            ds.receive(dp); //阻塞

            //解析数据
            String ip = dp.getAddress().getHostAddress();
            String hostName = dp.getAddress().getHostName();
            String s = new String(dp.getData(), 0, dp.getLength());


            System.out.println(ip+":"+hostName+"发送来数据:"+s);
        }

    }
}

运行结果

 


TCP协议
 TCP协议发送数据:
     1、创建发送端的Socket对象
         这一步一旦成功了,说明连接建立成功
     2、获取输出流对象,写数据
     3、释放资源

TCP编程先启动服务器端,否则报错
ConnectException: Connection refused: connect
TCP服务端接收数据:
    1、创建服务器端的Socket对象
    2、监听客户端的连接,返回一个相应的Socket对象
    3、获取输入流对象,读取数据显示在控制台上
    4、释放资源
参考代码
ServerDemo3:
import java.io.BufferedReader;

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

public class ServerDemo3 {
    public void chat(){
        try {
            ServerSocket ss = new ServerSocket(10086);
            Socket s = ss.accept();

            String ip = s.getInetAddress().getHostAddress();

            BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
            String line = null;
            while ((line = br.readLine())!=null){
                System.out.println(ip+":"+line);
            }
            s.shutdownOutput();
            s.shutdownInput();

            s.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    public static void main(String[] args) {
        new ServerDemo3().chat();
    }
}

 ClientDemo3:

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Scanner;

public class ClientDemo3 {
    public void chat(){
        Scanner sc = null;
        try {
            //创建TCP协议客户端的Socket对象
            Socket s = new Socket("192.168.3.145", 10086);
            System.out.println("请输入想要发送的数据:");

            //获取输出流对象
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

            while (true){
                sc = new Scanner(System.in);
                String next = sc.next();
                bw.write(next);
                bw.newline();
                bw.flush();
            }


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




    }



    public static void main(String[] args) {
        new ClientDemo3().chat();
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5686211.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存