现在的位置: 首页 > 综合 > 正文

黑马程序员_<<网络编程----UDP>>

2018年09月16日 ⁄ 综合 ⁄ 共 5885字 ⁄ 字号 评论关闭

---------------------ASP.Net+Android+IOS开发.Net培训、期待与您交流! --------------------

1.网络

       1.概述

              如果在网络之间应用程序能够通信,那么就需要三个元素(IP,端口和协议)

     IP:在网络上的每一个计算机,或者在网络上进行通信的工具,都需要标识自己,那么就会IP地址来标识,IP地址常用的是32位二进制,也有128位的二进制标识。

      端口:因为每一个设备上有很多应用程序,那么我们就需要来区分,标识这应用程序,就是每一个应用程序都有自己的端口号来标识自己,都是用数字进行标识。是逻辑地址。0~65535范围,其中0~1024不能使用,因为系统端口号或者保留端口。

     协议:就是在网络上通信的规则,必须双方都遵守这个规则,那么双方才能通信,有很多协议的,我们常用的是TCP/IP,UDP协议。

     网络模型:OSI参考模型和TCI/IP模型

            OSI参考模型:应用层,表示层,会话层,传输层,网络层,链路层,物理层

           TCP/IP体系:应用层,传输层,互联层,主机网络层

      2.InetAddress

         

import java.net.InetAddress;
 
public class InterAddressDemo {
  public static void main(String[] agrs) throws Exception {
    /**
     * 获得本机地址,名字和IP
     */
    InetAddress ia = InetAddress.getLocalHost();
    System.out.println(ia);
    System.out.println("名字:" +ia.getHostName());
    System.out.println("地址:" +ia.getHostAddress());
    /**
     * 获得百度的,
     * 地址和名字可能不唯一,因为百度对应多个IP和地址
     */
    InetAddress ia1=InetAddress.getByName("www.baidu.com");
    System.out.println(ia1);
    System.out.println("名字:" +ia1.getHostName());
    System.out.println("地址:" +ia1.getHostAddress());
  }
}
结果:
yang-PC/192.168.1.101
名字:yang-PC
地址:192.168.1.101
www.baidu.com/220.181.111.148
名字:www.baidu.com
地址:220.181.111.148

 

     3.传输协议

           UDP:面向无连接的(发数据之前不需要建立连接,打成包,)。不可靠协议,速度快,数据报大小限制在64k内,速度快,例如:qq,网络会议

      TCP:要建立连接,可以传输大量数据  通过三次握手玩成连接是可靠协议   必须建立连接,效率低,例如:下载,打电话

 

     

2. Socket

      1.Socket

Socket就是为网络服务提供的一种机制

通信的两端都有Socket

网络通信其实就是Socket的通信

数据在两个Socket间通过IO传输

 

      2. UDP-DatagramSocket

         创建步骤:

1.建立发送端和接收端

2.建立数据包。

3.调用Socket的发送和接受方法

4.关闭Socket

需求:通过UDP传输方式,将一段文字发送出去。

1.建立udpsocket服务

2.提供数据,将数据封装到数据包中

3.通过Socket服务的发送功能,将数据包发出去

4.关闭资源

 接收:

需求:定义一个应用程序,用于接收数据并处理

1.定义UDF服务

2.定义一个数据包(无数据,用于存储接收到的字节数据),用其方法提取在包中数据信息

3.通过receive方法接受数据

4.从数据包中提取信息,然后打印在控制台上

5,关闭资源


     发送

    import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
 * 发送端
 */
public class UdpSend {
  public static void main(String[] args) throws Exception{
    /**
     * 定义服务,可以指定当前端口,如果不指定那么就是随机的
     *   定义数据包,指定要发送信息,长度,对方的地址和端口
     *   发送,关闭
     */
        DatagramSocket socket=new DatagramSocket(20000);//如果不指定,那么就是随机分配
        String str="hello world";
        DatagramPacket packet=newDatagramPacket(str.getBytes(),str.length(), “192.168.1.101”,10000);
        socket.send(packet);//发送
        socket.close();
  }
 
}

接收

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
 * 接收端
 */
public class UdpReceive {
  public static void main(String[] args) throws Exception {
    /**
     * 定义服务,指定本端口号,此端口号要和发送端发动的地址一样定义数据包,然后从数据包中提取信息,关闭
     */
    DatagramSocket socket = new DatagramSocket(10000);
    byte[] buf = new byte[1024];
    DatagramPacket packet = new DatagramPacket(buf, buf.length);
    socket.receive(packet);// 接收这是一个阻塞方法
    System.out.println(packet.getAddress().getLocalHost());
    System.out.println("信息:"
         + new String(packet.getData(), 0, packet.getLength()));
    System.out.println("端口号:" + packet.getPort());
    socket.close();
  }
 
}
结果:
yang-PC/192.168.1.101
信息:hello world
端口号:20000

         3.键盘录入发送

              发送端

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
 * 发送端
 */
public class UdpSend {
  public static void main(String[] args) throws Exception{
    /**
     * 定义服务,可以指定当前端口,如果不指定那么就是随机的
     * 键盘循环录入
     * 定义数据包,指定要发送信息,长度,对方的地址和端口
     *   发送,关闭
     */
        DatagramSocket socket=newDatagramSocket(20000);//如果不指定,那么就随机分配
        BufferedReader br=new BufferedReader(newInputStreamReader(System.in));
        String line=null;
        while((line=br.readLine())!=null){
        if(line.equals("886"))
          break;
        DatagramPacketpacket=new DatagramPacket(line.getBytes(),line.length(),“192.168.1.101”,10000);
        socket.send(packet);//发送
        }   
        socket.close();
  }
 
}

接收端

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
 
/**
 * 接收端
 */
public class UdpReceive {
  public static void main(String[] args) throws Exception {
    /**
     * 定义服务,指定本端口号,此端口号要和发送端发动的地址一样定义数据包,
     * 循环接收数据
     * 然后从数据包中提取信息
     */
    DatagramSocket socket = new DatagramSocket(10000);
    while (true) {
      byte[] buf = new byte[1024];
      DatagramPacket packet = new DatagramPacket(buf, buf.length);
      socket.receive(packet);// 接收这是一个阻塞方法
      System.out.println(packet.getAddress().getLocalHost());
      System.out.println("信息:"
           + new String(packet.getData(), 0, packet.getLength()));
      System.out.println("端口号:" + packet.getPort());
    }
  }
 
}

 

 

向广播地址发的话,那么就会所有的计算机当前网络都会收到。

 

要是想扩展的话,比如:把接收到的数据存到文件中,那么就读取一条信息就开始存,这样循环存储,道理是一样的。

         4 .聊天程序

因为有发和接收,所以需要用到同步,那就用到了多线程。

 发送端

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
 * 发送端
 * 里面封装了一个服务对象
 * 使用了键盘的录入
 *
 */
public class CharSend implements Runnable {
 
  private DatagramSocket sock;
 
  public CharSend(DatagramSocket sock) {
    this.sock = sock;
  }
 
  public void run() {
    BufferedReader bufR = new BufferedReader(new InputStreamReader(
         System.in));
    String line = null;
    try {
      while ((line = bufR.readLine()) != null) {
         if (line.equals("baibai"))
           break;
         byte[] bu = line.getBytes();
         DatagramPacket pac = new DatagramPacket(bu, bu.length,
             InetAddress.getByName("192.168.1.101"), 30001);
         sock.send(pac);
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
    sock.close();
  }
 
}
 

接收端

 

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
 
/**
 * 接收端循环的接收
 */
public class CharReceive implements Runnable {
  private DatagramSocket sock;
 
  public CharReceive(DatagramSocket sock) {
    this.sock = sock;
  }
 
  public void run() {
 
    while (true) {
     
      try {
         byte[] bu = new byte[1024];
         DatagramPacket pac = new DatagramPacket(bu, bu.length);
         sock.receive(pac);
         String ip = pac.getAddress().getHostAddress();
         byte[] data = pac.getData();
         String da = new String(data, 0, pac.getLength());
         int port = pac.getPort();
         System.out.println(ip + ":" + da + ":" + port);
      } catch (IOException e) {
         System.out.println("接受失败");
      }
    }
 
  }
 
}

 

测试

import java.net.DatagramSocket;
import java.net.SocketException;
/**
 * 测试类
 * @author yang
 *
 */
public class CharText {
  public static void main(String[] args) throws SocketException {
    DatagramSocket send = new DatagramSocket();// 发送服务
    DatagramSocket rece = new DatagramSocket(30001);// 接受服务,此时的端口号要和发送端要发送的端口育养
    new Thread(new CharReceive(rece)).start();// 开始接收
    new Thread(new CharSend(send)).start();// 开启发送
  }
 
}
 

 结果

结果:
你好
192.168.1.101:你好:51813
大家好
192.168.1.101:大家好:51813
很高兴认识你
192.168.1.101:很高兴认识你:51813
 

 ---------------------ASP.Net+Android+IOS开发.Net培训、期待与您交流!
--------------------

抱歉!评论已关闭.