分享

探索Java中的网络编程技术

 兰亭文艺 2019-01-16

网络编程就是io技术和网络技术的结合,网络模型的定义,只要共用网络模型就可以两者连接.网络模型参考.

图片说明


图片说明


一座塔有七层,我们需要闯关.

第一层物理层->第二层数据链路层->第三层网络层->第四层传输层->第五层会话层->第六层表示层->第七层应用层.

物理层是主要定义物理设备标准,数据链路层是主要讲从物理层接收的数据进行MAC地址(网卡的地址)的封装与解封装.这层的数据较帧.

网络层是将从下层接收到的数据进行IP地址的封装和解封装.传输层是定义一些传输数据的协议和端口号.

会话层是将通过传输层建立数据传输的通路.表示层是进行对接收的数据进行解释,加密与解密.

应用层主要是一些终端的应用.

应用层 --> 传输层 --> 网络层 --> 主机至网络层

图片说明


图片说明


电脑通讯要点:
一需要IP地址:InetAddress(互联网协议即是规则)
二需要端口号
三需要传输协议

IP地址,网络中设备的标识,不容易记住,可以用主机名,本地回环地址: 127.0.0.1 主机名就是 localhost了.所谓局域网就是局部范围内的,互联网就是全球的.

端口号是用来标识进程的逻辑地址,不同进行的标识,有效的端口为0到65535,其中0到1024系统使用或保留的端口.

传输协议即是通讯的规则,常见的协议为TCPUDP.

java.net

类 InetAddress

java.lang.Object
-> java.net.InetAddress


所有已实现的接口有:


Serializable


直接已知子类:


Inet4Address, Inet6Address


public class InetAddress extends Object implements Serializable


这个类表示互联网协议已地址.

图片说明


图片说明


Class Inet6Address

java.lang.Object
java.net.InetAddress
java.net.Inet6Address


public final class Inet6Address extends InetAddress


图片说明


获取ip地址:

public class IPDemo {
public static void main(String[] args) throws UnknownHostException {
 //获取本地主机地址对象
 InetAddress ip = InetAddress.getLocalHost();
 System.out.println(ip.getHostAddress() + ':' + ip.getHostName());
}
}


域名解析

C:WINDOWSsystem32driversetc


InetAddress方法

类型方法说明
booleanequals(Object obj)将此对象与指定对象进行比较
byte[]getAddress()返回此InetAddress对象的原始ip地址.
static InetAddress[]getAllByName(String host)给定主机的名称,根据系统上配置的名称服务返回其ip地址数组.
static InetAddressgetByAddress(byte[] addr)给出原始IP地址的InetAddress对象
static InetAddressgetByAddress(String host, byte[] addr)根据提供的主机名和ip地址创建InetAddress
static InetAddressgetByName(String host)确定主机名称的ip地址
StringgetCanonicalHostName()获取此ip地址的完全限定域名
StringgetHostAddress()返回文本显示中的ip地址字符串
StringgetHostName()获取此ip地址的主机名

网络编程:

1,网络模型:7层--->4层

端口

  1. 用于标识进程的逻辑地址,不同进程的标识

  2. 有效端口:0到65535,而0到1024系统使用或保留端口

传输协议

常见协议TCP``UDP

TCP和UDP的区别:

TCP: 面向连接,通过三次握手完成,速度慢,可靠。
UDP: 面向无连接,速度快,不可靠。

UDP是将数据及其源和目的封装成数据包中,不需要建立连接,每个数据报的大小在限制在64k内,因无连接,是不可靠的协议,不需要连接,但是速度快.

TCP是需要进行连接的,形成传输数据的通道,在连接中进行大数据量传输,通过三次握手完成连接,是可靠的协议,效率低即是速度慢一点.

网络编程-Socket

网络通讯的要素:

  1. ip

  2. 端口

  3. 传输协议

ip是用于标识网络中主机的数字标识,而端口是用于标识应用程序的数字,还有传输协议是用于进行数据传输的规则.

实现UDP的通信,TCP传输:客户端,服务端.

Socket是网络服务提供的一种机制,是通信两端必备的,都要有Socket,网络通信其实就是Socket间的通信,数据在两个Socket间通过io传输.

两端发送端和接收端-UDP

UDP发送端Demo

public class UDPSend{
public static void main(String[] args){
 System.out.println('udp发送端');
}
}


DatagramSocket


public class DatagramSocket extends Object


此类表示用来发送和接收数据报包的套接字.

数据报套接字是包投递服务的发送或接收点.每个在数据报套接字上发送或接收的包都是单独编址和路由的.从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达.

DatagramSocket上总是启动UDP广播发送.为了接收广播包,将DatagramSocket绑定到通配符地址.

图片说明


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


public class UDPSend{
public static void main(String[] args) throws IOException{
 System.out.println('udp发送端');
 DatagramSocket ds = new DatagramSocket();
 String text = 'hello';
 byte[] buf = text.getBytes();
 // 将数据转成字节数组
 DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName('123.23232.323.2'),10000);
 ds.send(dp);
 ds.close();
}
}
// 建立upd的socket,具备发送或接收功能
// 将数据封装到数据包中,数据包对象是DatagramPacket.
// 使用socket对象的send方法将数据包发出去.
// 关闭资源


udp接收端


public class updDemo {
public static void main(String[] args) throws IOException {
 System.out.println('udp 接收端');
 // 先有udpsocket服务
 // 接收数据
 DatagramSocket ds = new DatagramSocket();
 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());
 // 关闭资源。
 ds.close();
}
}


receive


public void receive(DatagramPacket p) throws IOException
此套接字接收数据报包


实现UDP的通信,udp传输涉及的两个对象,即可以发送,又可以接收.TCP传输:客户端,服务端.

UDP键盘输入

public class UDPSend {
   public static void main(String[] args) throws IOException {
       System.out.println('udp 发送端 run');
//      1,建立udp的socket它具备者发送或者接收功能。
       DatagramSocket ds = new DatagramSocket(9999);
//      2,将数据封装到数据包中。数据包对象是DatagramPacket。数据来自于键盘录入。
       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('192.168.1.223'), 10001);
//          3,使用socket对象的send方法将数据包发送出去。
           ds.send(dp);
       }
//      4,关闭资源。
       ds.close();
   }
}


public class UDPRece {
   public static void main(String[] args) throws IOException {
       System.out.println('udp2 接收端 run');
       DatagramSocket ds = new DatagramSocket(10001);
       while (true) {
           // 2,接收数据。
           // 3,先定义数据包。
           byte[] buf = new byte[1024];
           DatagramPacket dp = new DatagramPacket(buf, buf.length);
           ds.receive(dp);
           // 4,通过数据包对象获取数据包的内容,发送端的ip。发送端的端口,发送过来的数据。
           String ip = dp.getAddress().getHostAddress();
           int port = dp.getPort();
           String text = new String(dp.getData(), 0, dp.getLength());

           System.out.println(ip + ':' + port + ':' + text);
       }
       // 5,关闭资源。
//      ds.close();
   }
}


案例:


public class UDPChatTest {
   public static void main(String[] args) throws IOException {
       //发送端的socket 接收端的socket
       DatagramSocket sendSocket = new DatagramSocket();
       DatagramSocket receSocket = new DatagramSocket(10002);
       
       //创建任务对象。
       Send send = new Send(sendSocket);
       Rece rece = new Rece(receSocket);
       
       //创建线程并开启。
       Thread t1 = new Thread(send);
       Thread t2 = new Thread(rece);
       t1.start();
       t2.start();
   }

}

// 发送任务
class Send implements Runnable {

   private DatagramSocket ds;

   public Send(DatagramSocket ds) {
       super();
       this.ds = ds;
   }

   @Override
   public void run() {
       try {
           BufferedReader bufr = new BufferedReader(new InputStreamReader(
                   System.in));
           String line = null;
           while ((line = bufr.readLine()) != null) {
               byte[] buf = line.getBytes();// 将数据转成字节数组。
               DatagramPacket dp = new DatagramPacket(buf, buf.length,
                       InetAddress.getByName('1928.1.223'), 10002);
               ds.send(dp);
               if ('886'.equals(line)) {
                   break;
               }
           }

           // 4,关闭资源。
           ds.close();
       } catch (IOException e) {

       }
   }
}

// 接收任务。
class Rece implements Runnable {

   private DatagramSocket ds;

   public Rece(DatagramSocket ds) {
       super();
       this.ds = ds;
   }

   @Override
   public void run() {
       while (true) {

           try {
               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);
               if(text.equals('886')){
                   System.out.println(ip+'....离开聊天室');
               }
           } catch (IOException e) {

           }
       }

   }

}


tcp案例:


public class TCPClient {
   public static void main(String[] args) throws IOException {
       System.out.println('客户端运行.......');
//      1,建立tcp的客户端socket。明确服务端的地址和端口。
       Socket s = new Socket('192.1.223',10003);
//      2,如果通道建立成功就会出现socket io流。
//          客户端需要做的就获取socket流的中输出流将数据发送目的地服务端。
       OutputStream out = s.getOutputStream();
//      3,通过socket输出流将数据发送。
       out.write('hello tcp 来了!'.getBytes());
//      4,关闭资源。
       s.close();
   }
}


public class TCPServer {
   public static void main(String[] args) throws IOException {
       System.out.println('服务端开启.....');
       ServerSocket ss = new ServerSocket(10003);
       while (true) {
           Socket s = ss.accept();
           String ip = 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);
           s.close();
       }
   }
}


案例:


public class TCPClient2 {
   public static void main(String[] args) throws UnknownHostException, IOException {
       System.out.println('客户端2 启动.......');
       Socket s = new Socket('192.1623', 10004);
       OutputStream out = s.getOutputStream();
       out.write('服务端,我来了'.getBytes());
       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();
   }
}


public class TCPSever2 {
   public static void main(String[] args) throws IOException {
       System.out.println('服务端2启动.....');
       ServerSocket ss = new ServerSocket(10004);
       while (true) {
           // 获取客户端对象。
           Socket s = ss.accept();
           // 读取客户端的发送过来的数据
           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();
   }
}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多