Java网络编程

一,网络编程入门

网络编程:

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

1,网络编程三要素

        IP地址

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

        端口

                应用程序在设备中唯一的标识

        协议

                数据在网络中传输的规则,常见的协议有UDP协议和TCP协议

2,IP

IP:全称“互联网协议地址”,也称IP地址,是分配给上网设备的数字标签,常见的IP分为

ipv4和ipv6.

计算机通过域名像dns服务器获取ip地址,再通过ip地址访问想要访问的服务器,服务器再把数据展示再浏览器上。

        (1),ipv4:

                ipv4是32bit(4字节)的形式,采用的是点分十进制表示法

        (2),ipv6:

                由于互联网的蓬勃发展,IP地址的需求量越来越大,ipv4的模式下ip的总数是有限的。

                ipv6,采用126位地址长度,分为8组。采用的是冒分十六进制标识法

                特殊情况:如果计算出来的16进制表示形式中间有多个连续的0

                比如:FF01:0:0:0:0:0:0:1101 -------->  FF01::1101

3,IP地址

        常用命令:

        ipconfig:查看本机IP地址

        ping IP地址:检查网络是否连通

        特殊的IP地址:127.0.0.1 :是回送地址也称本地回环地址,可以代表本机的IP地址,一般用来测试使用

4,InetAddress的使用

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

   InetAddress:此类表示Internet协议(IP )地址

方法:static  InetAddress  getByName(String  host) ;确定主机名称的IP地址,主机名称可以是机器名称也可以是IP地址

        String  getHostName();获取此IP地址的主机名

        String  getHostAddress()返回文本显示中的IP地址字符串

public class Demo01 {
    public static void main(String[] args) throws UnknownHostException {
        //确定主机名称的IP地址
        InetAddress byName = InetAddress.getByName("DESKTOP-5P6P9BH");
        System.out.println(byName);
        //返回IP地址的主机名称
        String hostName = byName.getHostName();
        System.out.println(hostName);
        //返回IP地址以字符串的形式
        String hostAddress = byName.getHostAddress();
        System.out.println(hostAddress);

    }
}

 5,端口

        端口:应用程序再设备中的唯一标识

        端口号:用两个字节标识的整数,它的取值范围是0~65535.

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

                        我们可以使用的端口号是1024以上的

         注意:一个端口号只能被一个应用程序使用

6,协议

        协议:计算网络中,链接和通信的规则被称为网络通信协议

        UDP协议:

        用户数据协议

        UDP是面向无连接通信协议,速度快,有大小限制一次最多发送64k,数据不安全,易丢失数据。

        TCP协议:

        传输控制协议

        TCP协议是面向链接的通信协议,速度慢,没有大小限制,数据安全

7,小结

        网络编程:就是可以让两台计算机进行数据交互

        网络三要素:

                IP:设备在网络中唯一的标识

                端口号:应用程序在设备中唯一的标识

                协议:数据在传输过程中遵守的规则

二,UDP通信程序

1,UDP发送端

        创建发送端的DatagramSocket对象

        创建数据,并把数据打包(Datagrampacket)

        调用DatagramSocket对象的方法发送数据

        释放资源

public class ClientDemo01 {
    public static void main(String[] args) throws IOException {
        //1,建立网络中的链接
        DatagramSocket dgs = new DatagramSocket();
        
        String s = "礼物";//要传输的数据
        byte[] bytes = s.getBytes(StandardCharsets.UTF_8);//将数据转换称编码的形式
        InetAddress byName = InetAddress.getByName("127.0.0.1");//确定传输的IP地址
        int port = 20000;//确定端口号
        DatagramPacket dgp = new DatagramPacket(bytes,bytes.length,byName,port);
        dgs.send(dgp);

        dgs.close();

    }
}

2,UDP接收端

        创建接收端DatagramSocket对象

        创建一个箱子,用于接收数据

        调用DatagramSocket的方法接收数据并将数据放入箱子中

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

        释放资源

public class ServerDemo01 {
    public static void main(String[] args)throws IOException {
        DatagramSocket ds = new DatagramSocket(20000);

        byte[] bytes = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bytes,bytes.length);
        ds.receive(dp);

        byte[] data = dp.getData();
        int length = dp.getLength();
        System.out.println(new String (data,0,length));

        ds.close();

    }
}

 这一点:1,要先运行接收端,在运行发送端

               2,如果接收端在启动之后没有收到数据,那么就会死等(阻塞)

                3,在接收数据的时候,需要调用一个getlength方法,标识接收到了多少字节

3,UDP的三种通信方式

        单播, 组播,广播

UDP通信组播代码实现

        组播地址:224.0.0.0~239.255.255.255

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

组播发送端

public class ClientDemo01 {
    //组播的实现
    public static void main(String[] args) throws IOException {
        DatagramSocket ds = new DatagramSocket();

        String s = "hello 组播";
        byte[] bytes = s.getBytes(StandardCharsets.UTF_8);
        InetAddress byName = InetAddress.getByName("224.0.1.0");
        int port = 10000;
        DatagramPacket dp = new DatagramPacket(bytes,bytes.length,byName,port);

        ds.send(dp);
        ds.close();
    }
}

组播接收端

public class ServerDemo01 {
    public static void main(String[] args) throws IOException {
        MulticastSocket ms = new MulticastSocket(10000);

        DatagramPacket dp = new DatagramPacket(new byte[1024],1024);

        //把当前计算机绑定一个组播地址
        ms.joinGroup(InetAddress.getByName("224.0.1.0"));

        ms.receive(dp);

        byte[] data = dp.getData();
        int length = dp.getLength();
        System.out.println(new String(data,0,length));

        ms.close();

    }
}

 UDP广播代码实现

        广播地址255.255.255.255

广播发送端

public class CilentDemo01 {
    //广播的实现
    public static void main(String[] args)throws IOException {
        DatagramSocket ds = new DatagramSocket();

        String s = "广播";
        byte[] bytes = s.getBytes();
        InetAddress byName = InetAddress.getByName("255.255.255.255");
        int port  = 10000;
        DatagramPacket dp = new DatagramPacket(bytes,bytes.length,byName,port);

        ds.send(dp);

        ds.close();

    }
}

广播接收端(和单播的相同)

public class ServerDemo01 {
    public static void main(String[] args) throws IOException {
        DatagramSocket ds = new DatagramSocket(10000);

        DatagramPacket dp = new DatagramPacket(new byte[1024],1024);
        ds.receive(dp);

        int length = dp.getLength();
        byte[] data = dp.getData();
        System.out.println(new String (data,0,length));
        ds.close();
    }
}

三,TCP通信程序

TCP通信原理

        TCP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Soccket对象

        通信之间保证链接已经建立

        通过Socket产生IO流来进行网络通信   

    1,TCP发送数据步骤

         创建客户端Socket对象(Socket)与指定服务器连接

                Socket(String  host,int port)

        获取输入流,写数据

        释放资源

public class ClientDemo01 {
    public static void main(String[] args) throws IOException {
        //1,创建socket对象
        Socket sk = new Socket("127.0.0.1",11111);
        //2,获取一个IO流开始写对象
        OutputStream outputStream = sk.getOutputStream();
        outputStream.write("hello".getBytes(StandardCharsets.UTF_8));

        //3,释放资源
        outputStream.close();
        sk.close();
    }
}

2,TCP接收数据

        创建服务器端的Socket对象

        监听客户端连接,返回一个Socket对象

        获取输入流,读取数据,并把数据显示在控制台

        释放资源

public class ServerDemo01 {
    public static void main(String[] args) throws IOException {
        //1,创建socket对象
        ServerSocket sk = new ServerSocket(11111);
        //2,等待客户端链接
        Socket accept = sk.accept();
        //3,获得输入流对象
        InputStream inputStream = accept.getInputStream();
        int b;
        while((b = inputStream.read()) !=-1){
            System.out.println((char)b);
        }
        //4,释放资源
        inputStream.close();
        accept.close();
        sk.close();
    }
}

1,accept方法是阻塞的,作用就是等待客户端连接

2,客户端创建对象并连接服务器,此时是通过三次握手协议保证跟服务器之间的连接

3,针对客户端来讲,是往外写的,所以是输出流

       针对服务器来讲,是往里读的,所以是输入流

4,read方法也是阻塞的

5,在关流的时候,还多了一个往服务器写结束标记的动作

6,最后一步断开连接,通过四次挥手协议保证连接终止

3,三次握手

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

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

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

4,四次挥手

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

客户端        服务器向客户端返回一个响应,标识收到客户端取消请求  服务器端

客户端        服务器向客户端发出确认取消信息   服务器端

客户端        客户端再次发送确认信息,连接取消    服务器端

四,网络编程高级

服务端优化

        第一个弊端:服务器只能处理一个客户端请求,接收完一个图片之后,服务器就关闭了

        改进方式:循环

        第二个弊端:第二次上传文件的时候,会把第一次的文件给覆盖

        改进方式:UUID.randomUUID()方法生成随机的文件名

        加入循环后有引发了一个问题:

                        使用循环虽然可以然服务器处理多个客户端请求,但是还是i无法同时跟多个客户端进行通信

        改进方式:开启多线程处理

        加入多线程以后又引发一个问题:

                        使用多线程虽然可以让服务器同时处理多个客户端请求,但是资源消耗太大

        改进方式:使用线程池

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值