Java基础-网络编程

.1 网络编程定义

在网络通信协议下,不同计算机运行的程序,进行的数据传输。

应用场景:

                即时通信、网游对战

                计算机与计算机直接通过网络进行数据传输

Java中可以使用java.net包

.2 软件架构

C/S : 客户端/服务端    IDEA、 QQ

在用户本地需要下载并安装客户端程序

在远程有一个服务器端程序

        客户端服务端模式需要开发用户端

        适合定制专业化的办公类软件

B/S 浏览器/服务端  京东、淘宝

只需要一个浏览器,用户通过不同的网址

客户访问不同的服务器

        浏览器服务端模式不需要开发客户端

        适合移动互联网应用,可以在任何地方随时访问的系统

.3 网络编程三要素

.3.1 IP

设备在网络中的地址,是唯一的标识

分为 IPv4、 IPv6

InetAddress对象就是一台电脑的对象

public class InetAddressDemo1 {
    public static void main(String[] args) throws UnknownHostException {
        //获取InetAddress对象
        // 对象就是一台电脑的对象
        //                           IP地址或者计算机名
        InetAddress address = InetAddress.getByName("172.22.44.246");
        String name = address.getHostAddress(); //返回计算机名称 没有计算机名称就返回ip地址
        System.out.println(name);

        String ip = address.getHostAddress(); //返回IP地址
        System.out.println(ip);
    }
}

.3.1.1 IPv4

全称:Internet Protocol version 4 ,互联网通信协议第四版

采用32位地址长度,分成四组

11000000 10101000 00000001 01000010 通过点分十进制表示法192,168,1,66

IPv4的地址分类形式

        公网地址(万维网使用)和私有地址(局域网使用)

        192.168.开头的就是私有地址,范围即为192.168.0.0--192.168.255.255,专门为组织几个内部使用,解决IPv4 IP地址不够的时候(局域网)

特殊IP地址

        127.0.0.1,也可以是localhost: 是回送地址也称为本地回环地址,也称本机IP,永远只会寻找当前所在本机。(和局域网IP不一样)

.3.1.2  IPv6

全称:Internet Protocol version 6 ,互联网通信协议第六版

为了应对IPv4网络地址不够

采用128位地址长度,分成8组

采用冒分十六进制表示法

.3.1.3  常见CMD命令

ipconfig: 查看本机IP地址

ping: 检查网络是否连通

.3.2 端口号

应用程序在设备中唯一的标识        (一个端口号只能被一个应用程序使用)

端口号:由两个字节表示的整数,取值范围 0~65535

                其中0~1023之间的端口号用于一些知名的网络服务端或者应用

                我们自己使用1024以上的端口号就可以了

.3.3 协议

数据在网络中传输的规则

        常见的协议由 TCP、UDP、 http、https、ftp

.3.3.1 UDP协议

用户数据协议

UDP是面向无连接通信协议

速度快,有大小限制一次最大发送64K,数据不安全,易丢失数据

不管是否已经连接成功数据都会发送

.3.3.2 TCP协议 

传输控制协议TCP

TCP协议是面向连接的通信协议

速度慢,没有大小限制,数据安全

.3.3.3  TCP/IP参考模型

应用层 ----HTTP、FTP、Telnet、DNS

        一般是应用程序需要关注的,如浏览器,邮箱、程序员一般在这一层开发

传输层 ----TCP、UDP

         选择传输使用的TCP、UDP协议

网络层 ----IP、ICMP、ARP

         封装自己的IP,对方的IP等信息

物理+数据链路层(物理链路层) ----硬件设备二进制编码

        转换成二进制利用物理设备传输 

物理链路层是最底层。

.3.3.4 UDP的三种通信方式

发送端的端口号是随机的

但是接收端的端口号是有发送端指定的需要保持一致

.3.3.4.1 单播
//先启用接收端 在运行发送端
public class ReceiveMessageDemo {
    public static void main(String[] args) throws IOException {
        //接收数据

        //创建DatagramSocket对象
        //在接收的时候一定要绑定端口号
        // 而且端口号要给发送时指定接受的端口号一致
        DatagramSocket ds1 = new DatagramSocket(10088);

        //接收数据
        byte[] bytes1 = new byte[1024];
        //                 用整个字节数组去接收 也可以指定起止长度来确定数组接收的长度
        DatagramPacket dp1 = new DatagramPacket(bytes1, bytes1.length);
        //该方法是阻塞的
        //程序执行到这一步的时候会在这里死等
        //等发送端发送消息
        ds1.receive(dp1);

        //解析数据包
        byte[] data = dp1.getData();//数据
        int len = dp1.getLength();// 数据的大小
        InetAddress ia1 = dp1.getAddress();//发送端的ip
        int port1 = dp1.getPort(); //发送端的端口号

        System.out.println("接收到的数据:"+new String(data,0,len));
        System.out.println("发送数据的ip:"+ia1+"发送数据的端口号"+port1);
        ds1.close();
    }
}
public class SendMessageDemo1 {
    public static void main(String[] args) throws IOException {
        //发送数据

        //1.创建DatagramSocket对象
        //细节
        //绑定端口 以后我们就通过这个端口发送数据
        //空参 所有可用端口中随机一个使用
        //有参 指定端口使用
        DatagramSocket ds= new DatagramSocket();
        //打包数据  字节数组类型
        String str= "你好";
        byte[] bytes = str.getBytes();
                                                //这个IP是有当前连接的网络的局域网分配的
        InetAddress ia = InetAddress.getByName("172.22.121.78");//永远代表本机的IP地址127.0.0.1
        int port = 10088; //接受的端口号

        //创建发送数据
        DatagramPacket dp = new DatagramPacket(bytes, bytes.length,ia,port);
        ds.send(dp);

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

.3.3.4.2 组播

可以同时给多个发送

需要将发送端和多个接收端添加到统一组中如 都是224.0.0.0

组播地址 224.0.0.0 ~ 239.255.255.255

                其中224.0.0.0 ~ 224.0.0.255 为预留组播地址

//组播
public class ReceiveMessageDemo4 {
    public static void main(String[] args) throws IOException {

        //创建创建MulticastSocket对象
        MulticastSocket ms= new MulticastSocket(10086);

        //将当前本机添加到224.0.0.0这一组当中
        InetAddress address = InetAddress.getByName("224.0.0.0");
        ms.joinGroup(address);

        //创建DatagramPacket对象
        byte[] bytes = new byte[2024];
        DatagramPacket dp = new DatagramPacket(bytes,0,bytes.length);

        //接收数据
        ms.receive(dp);

        //解析数据
        byte[] data= dp.getData();
        int len = dp.getLength();
        //当前本机局域网IP地址
        String ip = dp.getAddress().getHostAddress();
        String name = dp.getAddress().getHostName();
        System.out.println(name+ip+new String(data,0,len));

        //释放资源
        ms.close();
    }
}

public class SendMessageDemo4 {
    public static void main(String[] args) throws IOException {
        //组播发送端代码

        //创建MulticastSocket对象
        MulticastSocket ms= new MulticastSocket();

        //创建DatagramPacket对象
        String str = "你好!!";
        byte[] bytes = str.getBytes();
        InetAddress ia = InetAddress.getByName("224.0.0.0");
        int port = 10086;

        DatagramPacket dp = new DatagramPacket(bytes, bytes.length,ia,port);

        //发送数据
        ms.send(dp);

        //释放数据
        ms.close();
    }
}

.3.3.4.3 广播

广播地址: 255.255.255.255

//广播 地址是255,255,255,255
public class SendMessageDemo3 {
    public static void main(String[] args) throws IOException {
        //创建对象
        DatagramSocket ds = new DatagramSocket();
        //打包数据
        String str = "你好";
        byte[] bytes = str.getBytes();
        InetAddress ia = InetAddress.getByName("255.255.255.255");
        int port = 10088;
        DatagramPacket dp = new DatagramPacket(bytes, bytes.length,ia,port);

        //发送数据
        ds.send(dp);

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

.3.3.5 TCP通信程序

客户端 Socket

        创建客户端的Socket对象(Socket)与指定服务器连接  Socket(String host, int port)

        获取输出流,写数据  OutputStream getOutputStream()

        释放资源  void close ()

服务端 ServerSocket

        创建服务器的Socket 对象(ServerSocket)  ServerSocket(int port)

        监听客户端连接,返回Socket对象   Socket accept ()

        获取输入流,读数据,并把数据显示在控制台上  InputStream getInputStream()

        释放资源   void close()

TCP通信程序(三次握手) ---确保连接建立

        客户端向服务器发出连接请求----等待服务器确认

        服务器向客户端返回一个响应----告诉客户端收到了请求

        客户端向服务器再次发出确认信息----连接建立

TCP通信程序(四次挥手)----确保连接断开,且数据处理完毕

        客户端向服务器发出取消连接请求

        服务器向客户端返回一个响应----表示收到客户端取消请求

        (服务器将最后的数据处理完毕后)服务器向客户端发出确认取消信息

        客户端再次发送确认消息----连接取消

遇到的额外事项

 bw.flush() 可以防止数据丢失
bw.flush() 方法用于强制将 BufferedWriter 中的所有缓冲数据写入到输出流中。BufferedWriter 使用内存中的缓冲区来积累数据,以提高写入效率。当你调用 flush() 方法时,所有在缓冲区中的数据会被写入到目标文件或输出流中。

作用:
确保数据写入:在调用 flush() 之后,你可以确保所有的数据已经被写入,而不是仅仅在缓冲区中。对于网络传输或文件写入等操作,flush() 是一个重要步骤,确保数据在流被关闭之前被完全写出。
防止数据丢失:如果你在关闭流之前没有调用 flush(),可能会导致数据未完全写出,这可能会导致数据丢失或输出不完整。

//服务端
public class Sever1 {
    public static void main(String[] args) throws IOException {

        //创建ServerSocket对像 绑定对应的端口号
        ServerSocket ss = new ServerSocket(10086);

        //监听客户端的链接 一直等
        Socket socket = ss.accept(); //等待客户端链接

        //从连接通道中获取输入流对象
        //服务端接收是可以通过转化流变成字符流 在封装成字符缓冲流
/*        InputStream is = socket.getInputStream();
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);*/
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        int len;

        while ((len = br.read()) != -1){
            System.out.print((char)len);
        }

        //释放资源
        br.close();
        ss.close();
    }
}
//客户端
public class Client1 {
    public static void main(String[] args) throws IOException {

        //创建Socket对象
        // 在创建对象的时候会连接服务器

        Socket sk = new Socket("172.22.44.246",10086);

        //从连接通道中获取输出流  客户端只能是字节输出流
        OutputStream os= sk.getOutputStream();
        //写出数据
        os.write("你好,我也好!!!".getBytes());
        //释放资源
        os.close();
        sk.close();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值