Java基础-网络编程(十)

一、网络编程概述

1.概念

1、网络:计算机网络,由在不同地理位置、不同的计算机主机,互联形成的一个计算机系统。有通讯和数据共享的作用。
2、网络编程:在已经拥有完备成熟的网络系统之后,在整个基础上,使用网络进行编程,对应用层进行设计的活动。
在这里插入图片描述

2.目的

在这里插入图片描述

二、网络编程三要素

1、在网络编程中,必须要使用的三个基本的通信数据
2、IP地址、端口号、通信协议
(1)IP地址:网络中每一台计算机的唯一标识,通过IP地址找到指定的计算机。
(2)端口:用于标识进程的逻辑地址,通过端口找到指定进程。
(3)协议:定义通信规则,符合协议则可以通信,不符合不能通信。

1.TCP/IP

1.1.IP地址

1、在一个计算机网络中,某台计算机在网络中的唯一标志
2、分类:
(1)IPv4:192.168.2.84
使用4个0-255的数字,来表示一个ip地址,32位,2^32个地址,40亿四个字节中,可能有2个字节或者3个字节表示所在的子网剩余的部分是在子网中的IP号码
在一个子网中,使用一个字节表示,0-255 0表示子网的网号:192.168.2.0就表示当前的子网网号 255表示广播地址(在整个子网中的所有地址,都会接收到发送到广播地址的数据)特殊的IP地址:127.0.0.1,表示本地回环地址,表示当前正在运行这个程序的Ip相关的命令:ipconfig(查询当前网卡信息) ping(查看某个IP是否联通)
(2)IPv6:
由8组数字组成,每组数字都是4个16进制数(每个数字16种状态,32数字)
(3)127.0.0.1: 本机 localhost

TCP/IP 参考模型
在这里插入图片描述
在这里插入图片描述
总结:

  1. 网络编程中有两个主要的问题
    如何准确的定位到网络上的一台或者多台主机
    找到主机之后如何进行通信
  2. 网络编程中的要素
    IP和端口号 IP
    网络通信协议 udp,tcp
  3. 万物皆对象
/**
 * @author Daniel
 * 测试IP
 */
public class TestIndress {

    public static void main(String[] args) {
    /**
 *      1、用于描述ip地址的对象所属的类型(主机名称、ip地址)
 *  	2、获取方式:
 *  	getByName(String host): 根据主机名称获取当前类型对象
 *  	getByAddress(byte[] arr):根据ip地址的字节数组获取当前类型对象
 *  	getAllByName(String host):根据主机名称获取的所有当前类型对象的数组
 *  	getLocalHost():获取当前主机的当前类型对象
 * 	    3、对象的常用方法:
 *  	getHostName():获取主机名称
 *  	getAddress():获取ip地址的字节数组
 *  	toString():同时获取主机名称和ip地址的字符串表示
 */
        try {
            //查询本机地址
            InetAddress inetAddress1 = InetAddress.getByName ( "127.0.0.1" );
            System.out.println (inetAddress1);
            InetAddress inetAddress2 = InetAddress.getByName ( "localhost" );
            System.out.println (inetAddress2);
            //查询网站ip地址
            InetAddress inetAddress3 = InetAddress.getByName ( "www.baidu.com" );
            System.out.println (inetAddress3);
            InetAddress localHost = InetAddress.getLocalHost ();//域名或自己电脑的名字

            System.out.println (localHost);

            System.out.println ( inetAddress2.getAddress () );//IP
            System.out.println ( inetAddress2.getCanonicalHostName () );//规范的名字
            System.out.println ( inetAddress2.getHostAddress () );//域名或自己电脑的名字

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

运行结果为:
在这里插入图片描述

1.2.端口号

1、也是一个数字,就是用于标记在电脑中的某个进程
2、使用两个字节来表示端口号:0-65535
也就是说,在计算机中,同时运行着的进程,最多只能有65536个
当程序运行时,需要有一个端口号,在程序运行结束之后,端口号被收回
3、在网络程序中,先在网络中通过ip地址,找到计算机,然后通过端口号找到对应的进程。
4、分配:在程序启动的时候,可以使用程序中指定的端口号,也可以随机分配
5、常用的端口号:
操作系统:0-1024之间
公有端口:0-1023
HTTP:80
HTTPS:443
FTP:21
MySQL:3306
Oracle:1521
Tomcat:8080

netstat -ano #查看所有的端口  	
netstat -ano | findstr "5900" #查看指定的端口   
tasklist | findstr "8696"  #查看指定端口的进程    如qq

快捷打开任务管理器 :Ctrl+Shift+Esc

/**
 * @author Daniel
 * InetSocketAddress
 */
public class InetSockTest {

    public static void main(String[] args) {

        InetSocketAddress inetSocketAddress1 = new InetSocketAddress ( "127.0.0.1", 8080 );
        System.out.println (inetSocketAddress1);
        InetSocketAddress inetSocketAddress2 = new InetSocketAddress ( "localhost",8080 );
        System.out.println (inetSocketAddress2);

        System.out.println ( inetSocketAddress1.getPort () );
        System.out.println ( inetSocketAddress1.getHostName () );
    }
}

运行结果为:
在这里插入图片描述

在这里插入图片描述

2.通信协议

在这里插入图片描述
TCP & UDP 对比

TCP:打电话
连接,稳定
三次握手 & 四次挥手

  1. 最少需要三次,保证稳定连接!
  2. A:你瞅啥?
  3. B:瞅你咋地?
  4. A:立新湖干一场!
  1. A:我要走了!
  2. B:我真的要走了吗?
  3. B:你真的真的要走了吗?
  4. A:我真的要走了!

客户端、服务端
传输完成,释放连接,效率低

UDP:发短信
不连接,不稳定
客户端、服务端:没有明确的界限
不管有没有准备号,都可以发给你……
如:导弹攻击
DDOS:洪水攻击!(饱和攻击)

3.TCP编程

1、使用的通信点就是Socket类型
2、客户端和服务端获取Socket对象的区别:
(1)客户端使用Socket的构造方法,创建一个Socket对象
(2)服务端不能使用自己创建的方式,而是使用服务端一个特殊的对象ServerSocket,接收客户端发来的请求,生成一个为这个客户端服务的Socket对象
3、构造方法:
Socket(InetAddress ip, int port):建立一个通信点,专门用于和ip主机的port程序进行通信。
只要这个对象创建成功了,就说明这个连接已经建立起来了,就说明当前的客户端已经联系上服务端了,已经获取了服务端返回的响应。
在创建对象的过程,就是在请求和服务端连接的过程。
4、服务端获取Socket对象的方式:
(1)启动一个服务程序,类型是ServerSocket,可以接收客户端发来的连接请求,一旦接收到请求,就可以创建一个和当前客户端交互的Socket对象
(2)ServerSocket的构造方法
ServerSocket(int port):创建一个服务端Socket对象,等待访问port端口的客户端
(3)accept():接收一个客户端发来的请求,返回一个服务此客户端的Socket对象
5、获取客户端和服务端的连接
(1)两个方法:
InputStream getInputStream():获取Socket对象的网络输入流
OutputStream getOutputStream():获取Socket对象的网络输出流
(2)一旦获取了输入输出流,就可以通过I\O的方式,来操作网络数据的传输。
(3)对应关系:
客户端的网络输入流,对应服务端的网络输出流
客户端的网络输出流,对应服务端的网络输入流
6、TCP编程步骤
客户端:
(1)创建Socket对象,建立和服务端的连接
(2)获取网络输入流和网络输出流
(3)通过I\O的操作来进行数据传输
服务端:
(1)创建ServerSocket对象,开启服务器,监听指定端口
(2)调用accept方法,接收客户端发来的请求,返回一个Socket对象
(3)获取服务端的网络输入流和网络输出流
(4)通过I\O的操作来进行输出传输
7、TCP编程加强:
(1)让客户端也接收数据,服务端也发送数据
(2)让字节流进行加强,转成字符流,加强成缓冲字符流
(3)让服务端多线程,同时可以处理多个用户的请求

TCP实现聊天

/**
 * @author Daniel 
 * 服务端
 */
public class ServerTcpDemo {

    public static void main(String[] args) {

        ServerSocket socket = null;
        Socket accept = null;
        InputStream is = null;
        ByteArrayOutputStream bos = null;

         try {
                //1.我得有一个地址
                socket = new ServerSocket ( 9999 );
                    while(true){
                        //2.等待客户端连接过来
                        accept = socket.accept ();
                        //3.读取客户端信息
                        is = accept.getInputStream ();
                        //管道流
                        bos = new ByteArrayOutputStream ();


                        byte[] buffer = new byte[1024];

                        int len;
                        while ((len = is.read (buffer))!= -1) {
                            bos.write ( buffer, 0, len );
                        }
                        System.out.println (bos.toString ());
                    }


            } catch (IOException e1) {
                e1.printStackTrace ();
            }finally {

             if(bos != null){
                 try {
                     bos.close ();
                 } catch (IOException e) {
                     e.printStackTrace ();
                 }
             }
             if(is != null){
                 try {
                     is.close ();
                 } catch (IOException e) {
                     e.printStackTrace ();
                 }
             }
             if(accept != null){
                 try {
                     accept.close ();
                 } catch (IOException e) {
                     e.printStackTrace ();
                 }
             }
             if(socket != null){
                 try {
                     socket.close ();
                 } catch (IOException e) {
                     e.printStackTrace ();
                 }
             }
         }
    }
}
/**
 * @author Daniel
 * 客户端
 */
public class ClientTcpDemo {

    public static void main(String[] args) {
        InetAddress serverIp = null;
        Socket socket = null;
        OutputStream out = null;
        try {
            //1.要知道服务器的地址 端口
             serverIp = InetAddress.getByName ( "127.0.0.1" );
                int port = 9999;
            //创建一个socket连接
             socket = new Socket (serverIp,port);
            out = socket.getOutputStream ();
            //发送socketIo流
            out.write ( "欢迎来Daniel的博客学习".getBytes () );
        } catch (Exception e) {
            e.printStackTrace ();
        }finally {
            if(out != null){
                try {
                    out.close ();
                } catch (IOException e) {
                    e.printStackTrace ();
                }
            }
            if(socket != null){
                try {
                    socket.close ();
                } catch (IOException e) {
                    e.printStackTrace ();
                }
            }
        }
    }
}

运行结果显示(先开启服务端再开启客户端)
在这里插入图片描述
TCP实现传输文件
(1)先准备要传输的图片,如下(放根目录下):在这里插入图片描述
(2)写客户端,服务端

/**
 * @author Daniel
 * 客户端
 */
public class FileTcpClientDaniel {
    public static void main(String[] args) throws Exception {

        //1.创建一个Socket连接
        Socket socket = new Socket ( InetAddress.getByName ( "127.0.0.1" ), 2024 );
        //2.创建一个输出流
        OutputStream os = socket.getOutputStream ();
        //3.读取文件
        FileInputStream fis = new FileInputStream ( new File ( "1.jpg" ) );
        //4.写出文件
        int len;
        byte[] bytes = new byte[1024];
        while ((len = fis.read ( bytes ))!= -1){
            os.write ( bytes,0,len );
        }
        //通知服务器我已经结束了
        socket.shutdownOutput ();//我已经传输完了!

        //确定服务器接收完毕,才能够断开连接
        InputStream inputStream = socket.getInputStream ();
        ByteArrayOutputStream bos = new ByteArrayOutputStream ();
        byte[] bytes1 = new byte[1024];
        int len1;
        while ((len1 = inputStream.read ( bytes1 ))!= -1){
            bos.write (bytes1,0,len1 );
        }
        System.out.println (bos.toString ());

        //关闭资源
        inputStream.close ();
        bos.close ();
        fis.close ();
        os.close ();
        socket.close ();
    }
}
/**
 * @author Daniel
 * 服务端
 */
public class FileTcpServerDaniel {
    public static void main(String[] args) throws Exception{
        //1.创建服务
        ServerSocket socket = new ServerSocket ( 2024 );
        //2.监听客户端的连接
        Socket accept = socket.accept ();
        //3.获取输入流
        InputStream is = accept.getInputStream ();
        //文件输出
        FileOutputStream fos = new FileOutputStream ( new File ( "66.jpg" ) );
        int len;
        byte[] bytes = new byte[1024];
        while ((len =is.read ( bytes ))!= -1){
            fos.write ( bytes,0,len );
        }
        //通知客户端我接收完毕了
        OutputStream outputStream =accept.getOutputStream ();
        outputStream.write ( "我已经接收到了,你可以断开连接了".getBytes () );

        //关闭资源
        fos.close ();
        is.close ();
        accept.close ();
        socket.close ();
        outputStream.close ();
    }
}

(3)先运行服务端,再运行客户端,运行结果显示目录下多出一个文件
在这里插入图片描述
在这里插入图片描述

4.UDP编程

1、使用的Socket是:DatagramSocket
2、构造方法:
DatagramSocket():不指定端口号,创建通信点,端口号随机分配,一般用于发送端
DatagramSocket(int port):指定端口号,创建通信点,一般用于接收端
3、成员方法:
send(DatagramPacket dp):将一个dp数据报包发送
receive(DatagramPacket dp):将数据接收到dp参数中
4、DatagramPacket介绍:
1、表示一个数据报数据的封装对象的类型
2、构造方法:
DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port)
buf:要发送的数据的字节数组
offset:从数组的哪个位置开始发送
length:发送多少数据
address:发送到哪个ip
port:发送到哪个程序
3、常用成员方法:
getData():返回该数据包中的字节数组
getLength():返回该数据包中接收到的字节个数
5、UDP编程的步骤:
发送端:
1、使用的Socket是:DatagramSocket
2、构造方法:
DatagramSocket():不指定端口号,创建通信点,端口号随机分配,一般用于发送端
DatagramSocket(int port):指定端口号,创建通信点,一般用于接收端
3、成员方法:
send(DatagramPacket dp):将一个dp数据报包发送
receive(DatagramPacket dp):将数据接收到dp参数中
4、DatagramPacket介绍:
1、表示一个数据报数据的封装对象的类型
2、构造方法:
DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port)
buf:要发送的数据的字节数组
offset:从数组的哪个位置开始发送
length:发送多少数据
address:发送到哪个ip
port:发送到哪个程序
3、常用成员方法:
getData():返回该数据包中的字节数组
getLength():返回该数据包中接收到的字节个数
5、UDP编程的步骤:
发送端:
(1)准备通信点对象
(2)准备发送的包裹对象
(3)调用通信点的发送方法
接收端:
(1)准备通信点对象
(2)准备接收端接收的容器
(3)调用通信点的接收方法
(4)解析接收到的数据准备通信点对象
(5)准备发送的包裹对象
(6)调用通信点的发送方法
接收端:
(1)准备通信点对象
(2)准备接收端接收的容器
(3)调用通信点的接收方法
(4)解析接收到的数据

//UDP编程  发送端
	public static void main(String[] args) throws IOException {
		// 创建通信点
		DatagramSocket ds = new DatagramSocket();
		byte[] b = "你好,我是周杰伦".getBytes();
		int len = b.length;
		InetAddress lh = InetAddress.getLocalHost();
		
		byte[] as ={(byte)192,(byte)168,2,84};
		
		byte[] a ={127,0,0,1};
		InetAddress ll = InetAddress.getByAddress(a);
//		System.out.println(lh.toString());
		//创建数据包
		DatagramPacket dp = new DatagramPacket(b, 0, len, ll, 9999);
		
		//调用send方法
		ds.send(dp);
		ds.close();
	}
}
public class ClientUdp {

    //udp接收端
    public static void main(String[] args) throws IOException {
        //创建通信点
        DatagramSocket ds = new DatagramSocket(9999);

        //创建一个数组
        byte[] bs = new byte[1024];
        int len = bs.length;
        //创建一个接受包
        DatagramPacket dp = new DatagramPacket(bs, len-1);
        //接受数据
        ds.receive(dp);
        byte[] data = dp.getData();
        int length = dp.getLength();
        System.out.println(new String(data,0,length));

    }
}

运行结果为:
在这里插入图片描述

5.URL

https://www.baidu.com/

统一资源定位符:定位资源的,定位互联网上的某一个资源
DNS域名解析 www.baidu.com xxx.x…x…x
协议://ip地址:端口/项目名/资源

/**
 * @author Daniel 
 * url
 */
public class UrlDaniel {
    public static void main(String[] args) throws Exception {
        URL url = new URL ( "https://localhost:8080/index/jsp?username=Daniel&password=123" );
        System.out.println ( url.getProtocol () );//协议
        System.out.println ( url.getPort () );//端口
        System.out.println ( url.getPath () );//文件
        System.out.println ( url.getHost () );//主机ip
        System.out.println ( url.getQuery () );//参数
        System.out.println ( url.getFile () );//全路径

    }
}

运行结果为:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Daniel521-Spark

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值