欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

第78节:Java中的网络编程(上)

程序员文章站 2022-05-23 12:22:29
第78节:Java中的网络编程(上) 前言 网络编程涉及ip,端口,协议,tcp和udp的了解,和对socket通信的网络细节. 网络编程 开放系统互连 网络编程指IO加网络 TCP/IP模型: 1. 应用层 2. 传输层 3. 网际层 4. 主机到网络层 OSI模型:(封装) 网络1封包 网络2拆 ......

第78节:Java中的网络编程(上)

第78节:java中的网络编程(上)

前言

网络编程涉及ip,端口,协议,tcp和udp的了解,和对socket通信的网络细节.

网络编程

第78节:Java中的网络编程(上)

osi开放系统互连

第78节:Java中的网络编程(上)

网络编程指io加网络

第78节:Java中的网络编程(上)

第78节:Java中的网络编程(上)

第78节:Java中的网络编程(上)

tcp/ip模型:

  1. 应用层
  2. 传输层
  3. 网际层
  4. 主机到网络层

osi模型:(封装) 网络1封包->网络2拆包

  1. 应用层
  2. 表示层
  3. 会话层
  4. 传输层
  5. 网络层
  6. 数据链路层
  7. 物理层

网络通讯要素:

  1. ip地址
  2. 端口号
  3. 传输协议

第78节:Java中的网络编程(上)

主机名和ip地址是对应的,默认的主机名:localhost

java.net
类 inetaddress

java.lang.object
-> java.net.inetaddress

已实现的接口: serializable
已知子类: inet4address, inet6address

public class inetaddress extends object implements serializable
该类表示互联网协议ip地址

ip地址是ip使用32或128位无符号数字,它是一种低级的协议,udp和tcp协议都是在它的基础上构建的.

inetaddress的实例包含ip地址,相应的主机名

升级:

java.net
类 inet6address

java.lang.object
-> java.net.inetaddress
-> java.net.inet6address

所有已实现的接口:serializable

public final class inet6address extends inetaddress
该类表示互联网协议第6版地址

获取ip地址

package com.dashucoding.ip;

import java.net.inetaddress;
import java.net.unknownhostexception;

public class ipdemo {

    public static void main(string[] args) throws unknownhostexception {
        // todo auto-generated method stub
        // ip地址对象 inetaddress

        // 获取本地主机地址对象
        inetaddress ip = inetaddress.getlocalhost();
        // 获取主机地址和主机名
        system.out.println(ip.gethostaddress() + ":" + ip.gethostname());

        inetaddress ip2 = inetaddress.getbyname("192.168.2.151");
        // 获取主机地址和主机名
        system.out.println(ip.gethostaddress() + ":" + ip.gethostname());

        // 主机名是需要进行解析的
    }

}

域名解析_查表

c:\windows\system32\drivers\etc

第78节:Java中的网络编程(上)

第78节:Java中的网络编程(上)

dns域名解析服务器,宽带服务.配置dns域名服务器主机,一个网址浏览要到它的ip地址,要找到,就会把ip地址放到dns域名解析服务器,供给本地使用宽带连接的使用,就可以在浏览器中找到ip地址,浏览网址了.

dns服务器软件,把你要浏览的地址ip写进去就可以了

有些软件需要进行注册序列号?

// hosts 文件配置
127.0.0.1 www.###.cn // 该域名地址

端口

端口,为物理端口,一台电脑发送信息给另一台电脑的软件,发送ip地址完, 要带上端口号, 然后 对应另一台接收消息的软件 有个软件应用程序的数字标识,为逻辑端口, 这样就可以对应发送到另一台电脑上的对应软件接收消息.

我今天要去一家酒店去了地址,到了楼层, 要知道哪个房间号,才知道对应做什么事.

第78节:Java中的网络编程(上)

传输协议

tcp和udp: 传输协议,传输规则,通讯规则,传输层.

第78节:Java中的网络编程(上)

udp,不需要建立连接.我发给你信息,不管你在不在,我就发给你了.我送你东西,写个地址,发到你家就行.有个包,装东西,有大小限制,最多是64k的限制数据.(好处,速度快,不可靠)

tcp发数据,要确保连接是不是畅通的.tcp是通过三次握手完成的,确保数据的连接畅通.用流行的话语:

完成了三次tcp握手:

女朋友发给男朋友
:"在吗?"

男朋友回复女朋友
:"我在!"

女朋友回复男朋友
:"我知道了"

这样爱情可靠,但是很浪费时间的,这样维护情感有点耗时,但是很可靠.

tcp断开就不传了,udp不管.电话来形容tcp,对讲机来形容udp.

socket

第78节:Java中的网络编程(上)

socke <-> socket
数据在两者之间通过io传输,传输协议tcp或udp

socket就像两端插口,传输协议不一样,socket插口也是由不同的类型的.数据在两者之间进行传输,数据是基于网络的io流进行传输的,传输过程就是传入和传出的过程

udp_发送端_out

java.net
class datagramsocket
java.lang.object
-> java.net.datagramsocket

all implemented interfaces: 
closeable, autocloseable
已知直接子类:
multicastsocket

public class datagramsocket extends object implements closeable
该类为用于发送和接收数据报数据包的套接字,数据报套接字是分组传送服务的发送或接收点.

例子:

datagramsocket s = new datagramsocket(null); 
s.bind(new inetsocketaddress(8888));

datagramsocket s = new datagramsocket(8888);

构造方法摘要

方法 说明
datagramsocket() 构造数据报套接字并将其绑定到本地主机上的任何可用端口
datagramsocket(datagramsocketimpl impl) 使用指定的datagramsocketimpl创建一个未绑定的数据报套接字
datagramsocket(int port) 构造数据报套接字并将其绑定到本地主机上的指定端口
datagramsocket(int port, inetaddress laddr) 创建一个数据报套接字,绑定到指定的本地地址
datagramsocket(socketaddress bindaddr) 创建一个数据报套接字,绑定到指定的本地套接字地址

receive(datagrampacket p):从此套接字接收数据报包
send(datagrampacket p):从此套接字发送数据报包

java.net
class datagrampacket
java.lang.object
-> java.net.datagrampacket

public final class datagrampacket extends object
该类表示数据报包

将数据封装到数据包中,数据包对象为datagrampacket 

数据包

datagrampacket(byte[] buf, int length)
// 字节数组来的

构造一个datagrampacket用于接收长度的数据包length.

receive
public void receive(datagrampacket p) throws ioexception
此套接字接收数据报包
返回, datagrampacket的缓冲区填充了接收的数据
数据报包也包含发送的ip地址和发送方的端口号

第78节:Java中的网络编程(上)

第78节:Java中的网络编程(上)

udpsend

package com.dashucoding.udp;

import java.io.ioexception;
import java.net.datagrampacket;
import java.net.datagramsocket;
import java.net.inetaddress;
import java.net.socketexception;
import java.net.unknownhostexception;

public class udpsend {

    public static void main(string[] args) throws ioexception {
        
        system.out.println("udp 发送端 run");
        // 先建立upd的socket 面向对象编程
        // 将数据封装到数据包中
        // 使用socket对象的send方法
        // 将数据包发送出去
        // 关闭资源
        datagramsocket ds = new datagramsocket();
        // 数据
        string text = "我是发送端,发送的数据";
        // 将数据转成字节数组
        byte[] buf = text.getbytes();
        // 将字节数据封装到数据包中
        datagrampacket dp = new datagrampacket(buf, buf.length, inetaddress.getbyname("你的ip地址"),10000);
        // 发送
        ds.send(dp);
        // 发完关掉,不然留着资源干嘛
        ds.close();
        
    }

}
package com.dashucoding.udp;

import java.io.ioexception;
import java.net.datagrampacket;
import java.net.datagramsocket;
import java.net.socketexception;

public class udprece {

    public static void main(string[] args) throws ioexception {
        system.out.println("udp 接收端 run");
        // 定义udp接收数据,显示在屏幕上
        // 先有插座嘛,udpsocket服务
        // 接收数据前 -> 先将数据存储到数据包中
        // 先定义数据包
        // 数据包对象会获取数据包中的内容,发送端的ip和端口
        // 关闭资源
        
        // 有upsocket服务
        datagramsocket ds = new datagramsocket(10000);
        // 接收数据,接收字节数据
        byte[] buf = new byte[1024];
        // 定义包
        datagrampacket dp = new datagrampacket(buf, buf.length);
        
        // 还没存到数据包,进行存储
        ds.receive(dp); // 阻塞
        
        string ip = dp.getaddress().gethostaddress();
        int port = dp.getport();
        string text = new string(dp.getdata(),0,dp.getlength());
        
        system.out.println(ip+" : "+port+" : "+text);
        // 关闭资源
        ds.close();
        
    }

}

键盘录入

发送端:

package com.dashucoding.udp2;

import java.io.bufferedreader;
import java.io.ioexception;
import java.io.inputstreamreader;
import java.net.datagrampacket;
import java.net.datagramsocket;
import java.net.inetaddress;
import java.net.socketexception;
import java.net.unknownhostexception;

public class udpsend2 {

    public static void main(string[] args) throws ioexception {
        // todo auto-generated method stub
        system.out.println("udp2 发送端 run");
        datagramsocket ds = new datagramsocket();
        // 数据来源于键盘录入
        bufferedreader bufr = new bufferedreader(new inputstreamreader(system.in));
        string line = null;
        while ((line = bufr.readline()) != null) {
            if("over".equals(line)) {
                break;
            }
            // 将数据转成字节数组
            byte[] buf = line.getbytes();
            // 将字节数据封装到数据包中
            datagrampacket dp = new datagrampacket(buf, buf.length, inetaddress.getbyname("你的ip地址"), 10002);
            ds.send(dp);
            // 发完关掉,不然留着资源干嘛
        }

        ds.close();
    }

}

接收端:

package com.dashucoding.udp2;

import java.io.ioexception;
import java.net.datagrampacket;
import java.net.datagramsocket;
import java.net.socketexception;

public class udprece2 {

    public static void main(string[] args) throws ioexception {
        // 有upsocket服务
        system.out.println("udp2 接收端 run");
        datagramsocket ds = new datagramsocket(10002);
        while (true) {

            // 接收数据,接收字节数据
            byte[] buf = new byte[1024];
            // 定义包
            datagrampacket dp = new datagrampacket(buf, buf.length);

            // 还没存到数据包,进行存储
            ds.receive(dp); // 阻塞

            string ip = dp.getaddress().gethostaddress();
            int port = dp.getport();
            string text = new string(dp.getdata(), 0, dp.getlength());

            system.out.println(ip + " : " + port + " : " + text);
            // 关闭资源
        }
        // ds.close();
    }
}

群聊工程

变化ip地址192.168.1.255

tcp

socket()
通过系统默认类型的socketimpl创建未连接套接字

socket(inetaddress address, int port)
创建一个流套接字并将其连接到指定ip地址的指定端口

socket(string host, int port)
创建一个流套接字并将其连接到指定主机上的指定端口号

getoutputstream()

返回此套接字的输出流

网络编程_tcp_服务端

第78节:Java中的网络编程(上)

package com.dashucoding.tcp;

import java.io.ioexception;
import java.io.outputstream;
import java.net.socket;
import java.net.unknownhostexception;

public class tcpclient {

    public static void main(string[] args) throws unknownhostexception, ioexception {
        // todo auto-generated method stub
        // 建立tcp的客户端socket 明确服务端的地址和端口
        // socket io流
        // 获取socket流
        
        system.out.println("客户端运行");
        // 建立tcp的客户端socket,明确服务端的地址和端口
        socket s = new socket("ip地址",20003);
        // socket输出流数据发送
        outputstream out = s.getoutputstream();
        // 通过socket输出流将数据发送
        out.write("hello tcp 来了".getbytes());
        // 关闭
        s.close();
    }

}
package com.dashucoding.tcp;

import java.io.ioexception;
import java.io.inputstream;
import java.net.serversocket;
import java.net.socket;

public class tcpserver {

    public static void main(string[] args) throws ioexception {
        // todo auto-generated method stub
        // 获取客户端的数据,在屏幕上

        // 思路
        // 创建服务端的socket,明确端口,监听一个端口
        // 服务端只要获取到链接过来的客户端就可以和指定的客户端通信了
        // 通过获取客户端的读取流对象读取客户端发来的数据.
        // 显示屏幕上
        system.out.println("服务端运行");

        // 创建服务端的socket,明确接收端口
        serversocket ss = new serversocket(20003);

        while (true) {
            // 服务端只要获取到连接过来的客户端就可以和指定的客户端通信
            socket s = ss.accept();
            string ip = s.getinetaddress().gethostaddress();
            system.out.println(ip + "...connected");

            // 通过获取客户端的读取流对象读取客户端发送来的数据
            inputstream in = s.getinputstream();
            // 流操作
            byte[] buf = new byte[1024];
            int len = in.read(buf);
            string text = new string(buf, 0, len);
            system.out.println(text);
            // 关闭
            s.close();
        }
        // ss.close();
    }

}

客户端和服务端交互

客户端:

package com.dashucoding.tcp2;

import java.io.ioexception;
import java.io.inputstream;
import java.io.outputstream;
import java.net.socket;
import java.net.unknownhostexception;

public class tcpclient2 {

    public static void main(string[] args) throws unknownhostexception, ioexception {
        // todo auto-generated method stub
        // 实现客户端和服务端的收发过程
        system.out.println("客户端2 启动");
        // 创建客户端的socket对象 
        socket s = new socket("ip地址",20004);
        // 发送数据,通过socket输出流完成
        outputstream out = s.getoutputstream();
        out.write("服务端,我来了".getbytes());
        
        // 读取服务端返回的数据,通过socket输入流
        inputstream in = s.getinputstream();
        byte[] buf=new byte[1024];
        int len = in.read(buf);
        string text = new string(buf,0,len);
        system.out.println(text);
        
        // 关闭资源
        s.close();
    }

}

服务端:

package com.dashucoding.tcp2;

import java.io.ioexception;
import java.io.inputstream;
import java.io.outputstream;
import java.net.serversocket;
import java.net.socket;

public class tcpserver2 {

    public static void main(string[] args) throws ioexception {
        // todo auto-generated method stub
        system.out.println("服务端2 启动");
        // 创建tcp服务端socket明确端口
        serversocket ss = new serversocket(20004);

        while (true) {
            // 获取客户端
            socket s = ss.accept();
            system.out.println(s.getinetaddress().gethostaddress() + "...");

            // 读取客户端的发送过来的数据
            inputstream in = s.getinputstream();
            byte[] buf = new byte[1024];
            int len = in.read(buf);
            string text = new string(buf, 0, len);
            system.out.println(text);
            // 给客户端回馈数据
            outputstream out = s.getoutputstream();
            out.write("客户端,我已经收到".getbytes());

            // 关闭客户端
            s.close();
        }
        // 关闭服务端
        // ss.close();
    }

}

第78节:Java中的网络编程(上)

第78节:Java中的网络编程(上)

小结

网络编程到网络模型:一开始7层到4层

传输层的了解

网络通讯:

  1. ip:用于网络中主机的数字标识
  2. 端口:用于应用程序的数字标识
  3. 传输协议:用于数据传输的规则

tcp和udp的区别

tcp: 面向连接,三次握手,速度慢,可靠
udp: 面向无连接,速度快,不可靠

实现udp的通信:

可以发送,又可以接收 datagramsocket datagrampacket 数据包对象

实现tcp传输:

客户端,服务端

客户端要明确服务端的ip+端口,而服务端要明确端口,通过accept的方法获取客户端对象.

结言

那么你是否掌握了,什么是tcp和udp,socket通信机制,以及ip,端口,协议.

达叔小生:往后余生,唯独有你
you and me, we are family !
90后帅气小伙,良好的开发习惯;独立思考的能力;主动并且善于沟通
简书博客: 达叔小生

结语

  • 下面我将继续对 其他知识 深入讲解 ,有兴趣可以继续关注
  • 小礼物走一走 or 点赞