黑马程序员_Java基础_网络编程_UDP传输协议编程,控制台聊天程序

  一,网络编程

1,网络通信概述:网络在我们生活中很常见,比如我们使用QQ,微信,MSN等聊天软件,都是通过网络进行数据传输的。实现这样的数据传输需要满足那些条件呢?能够满足这些条件的应用程序就可以看做是一个网络应用程序。当我们和别人之间使用这样的程序进行通信时,首先我们必须知道别人在哪里,知道别人的电脑主机地址,这个地址也就是我们很熟悉的IP地址。但是只知道别人的IP地址还不够,我们的电脑上安装了肯定不止一款通信软件,那么怎样才能把我这边通过QQ发送的消息发送到对方的QQ上,而不是微信上呢?这就要引入端口的概念,当我们找到别人的位置,也就是获取到别人的IP地址后,找到别人的主机,然后找相对应的端口,我用QQ发送消息,只有找到对方的QQ所对应的端口,发送到该端口,别人的QQ才能处理我发送的消息数据。

2,端口:网络中的端口是逻辑端口,其实就是每个应用程序对应的数字标示,比如QQ对应的端口是一个数字,微信对应的端口又是另外一个数字,这些数字之间不会冲突。并不是我们常见的诸如网线端口,USB端口的物理端口。常见端口:WEB服务端口是80tomcat服务器默认端口:8080mySQL默认是3306,当然这些是可以修改的,一旦端口被占用,另一个网络程序就不能使用该端口了。

3,通信规则:通过IP地址和端口,我们能将我QQ发送的数据发送到对方QQ上面,但是发送过程中还要满足一个条件,就是我们两个人必须使用相同的通信规则,这个通信规则就称为协议,国际组织定义的通信协议时TCP/IP协议。因为通信协议不止一种,我使用QQ给你发送消息,使用的是A协议,而你接受是通过B协议肯定是行不通的,只有双方遵守相同的协议通信才能成功。

4IP地址:IP地址是四端数字的排列组合,也就是我们熟知的IPV4地址,每一位的范围是0----255。例如:192.168.1.102。每台主机的IP地址是不一样的,后来为了解决IP地址不够用的问题就出现了IPV6地址,它支持字母和数字的组合,一共有八段。例如:2001:0DB8:0000:0000:0000:0000:1428:0000。我们自己电脑的IP地址可以通过命令行ipconfig命令查看,每台主机的本地回环地址是127.0.0.1,对应主机名是:localhost

 

二,网络参考模型


OSI的参考模型应用层,表示层,会话层对应TCP/IP参考模型的应用层,数据链路层和物理层对应TCP/IP参考模型的主机至网络层。Web应用程序的开发走的是应用层,而在学习网络编程的过程中我们直接操作的是传输层,关于应用层将在学习web开发时总结。
 

需求:获取本地IP地址和主机名的方法,以及获取指定网络主机的Ip地址。


import java.net.*;
public class InetAddressDemo
{
    public static void main(String[] args) throws Exception {
        //获取本地IP地址对象
        InetAddress i = InetAddress.getLocalHost();
        //获取本地主机名
        System.out.println("name:" + i.getHostName());
        //获取本地IP地址
        System.out.println("address:" + i.getHostAddress());
        System.out.println(i.getCanonicalHostName()); 
        //获取网络主机的InetAddress对象,获取百度的IP地址
        //InetAddress ie = InetAddress.getByName("www.baidu.com");//通过主机名获取InetAddress对象
        InetAddress[] ia = InetAddress.getAllByName("www.baidu.com");
        for(InetAddress i2: ia) {
            System.out.println("name:" + i2.getHostName());
            System.out.println("address:" + i2.getHostAddress());
        }
    }
}

三,网络通信协议:UDPTCP

1UDP通信协议:

(1)将数据及源和目的封装成包,不建立连接:发送方在发送数据的时候,不需要先建立连接,发送方只要将数据打包发送后就不管对方收不收的到了。

(2)数据包的大小有限制,一次只能发送64k,如果包超过64则分多次发送。

(3)面向无连接,所以协议不可靠,发送的数据包可能丢失。

(4)因为建立无连接,所以速度快。(比如聊天发送信息用的就是UDP协议,视屏会议,桌面共享都是UDP传输,就因为速度快)

 

2TCP通信协议:

(1)建立连接,形成传输数据的通道:必须先确定对方在才发送数据。

(2)连接中进行大数据的传输。

(3)通过三次握手完成连接,可靠协议。

(4)由于要建立连接,比UDP效率低。(比如下载视频,文件,使用的就是TCP/IP协议)

 

四,网络通信Socket

Socket是为网络服务提供的一种机制,通信的两端都有Socket,网络通信其实就是Socket通信,数据在两个Socket间是通过IO传输。

 

1,使用UDP协议发送数据的基本原理:

同时运行下面的两个程序,先启动接收端监听10000端口,然后启动发送端,接收端将接收到发送端的封装的数据。

需求一:通过Udp传输方式,将一段数据发送出去

思路:

1),建立udpsocket服务

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

3),通过socket服务的发送功能,将数据发送出去

4),关闭资源


import java.net.*;
class UdpSend
{
    public static void main(String[] args) throws Exception {
        //1,创建udp服务,通过Datagramsocket()构造函数;
        DatagramSocket ds = new DatagramSocket(9999);
        //指定发送端口号9999,那么接收端接收的就是9999端口发送的数据
        //2,提供数据并将数据封装到数据包,将数据发送到10000端口
        byte[] buf = "shu ju fa song".getBytes();
        DatagramPacket dp = new 
            DatagramPacket(buf,buf.length,InetAddress.getByName("27.19.74.69"),10000);
        //3,通过socket服务,将已有的数据包发送出去,通过send方法。send(DatagramPacket p)
        ds.send(dp);
        //4,关闭资源
        ds.close();
    }
}

需求二:定义一个程序,用于接收udp传输协议发送的数据,并处理。然后在定义udp接收端

 

思路:

   (1),建立udpsocket服务,通常会监听一个端口,其实就是给这个网络接受程序定义一个数字标示;

方便于明确哪些数据过来该应用程序能够处理。在不定义该标示时,默认是系统分配的。

   (2),定义一个数据包,因为要存储接收的字节数组,数据包对象中有根多的功能

能都对数据进行处理,提取字节数据中的不同信息。

   (3),通过socket服务的receive方法将收到的数据存储到定义好的数据包中

   (4),通过数据包对象的特有功能,将数据包中的字节数据进行提取,打印在控制台上

   (5),关闭资源 


class UdpRece
{
    public static void main(String[] args) throws Exception {
        //1,接收方创建udp socket,监听10000端口
        DatagramSocket ds = new DatagramSocket(10000);
        //2,定义数据包用于存储数据
        byte[] buf = new byte[1024];
        DatagramPacket dp = new DatagramPacket(buf,buf.length);
        //3,通过socket服务的receive方法将收到的数据存储到已经定义好的数据包
        ds.receive(dp);
        //receive是阻塞式方法,当没有数据时会等待数据
        //4,通过数据包的方法获取数据包中的数据
        String ip = dp.getAddress().getHostAddress();
        String data = new String(dp.getData(),0,dp.getLength());
        int port = dp.getPort();
        System.out.println(ip + "-----" + "-----" + data + "-----" + port);
        //5,关闭资源
        ds.close();
    }
}

五,UDP通信协议示例

1 ,需求:通过 UDP 协议,定义一个接收端和发送端,发送端通过键盘输入字符串,在接受端能够接受这些数据。当发送端输入 886 时,发送端结束。接收端可以一直监听发送端。


import java.net.*;
import java.io.*;
//建立发送端
class UpdSend2
{
    public static void main(String[] args) throws Exception {
        DatagramSocket ds = new DatagramSocket();
        //接受键盘输入
        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
        String line = null;
        while ((line = bufr.readLine())!=null)
        {
            if("886".equals(line))
                break;
            byte[] b = line.getBytes();
            //将接收到的每行字符串封装成数据包,然后发送到127.0.0.1主机的10001端口
            DatagramPacket dp = new DatagramPacket(b,b.length,InetAddress.getByName("127.0.0.1"),10001);
            ds.send(dp);
        }
        ds.close();
    }
}
//建立接收端
class UdpReceive
{
    public static void main(String[] args)throws Exception {
        DatagramSocket ds =new DatagramSocket(10001);//服务只建立一次,端口一旦被使用,其它程序就不能使用
        //本地主机的10001端口监听发送过来的数据包
        while (true)
        {
            byte[] b = new byte[1024];
            DatagramPacket dp = new DatagramPacket(b,b.length);
            ds.receive(dp);//阻塞式方法,没有数据传送进来时会一直等待
            //获取对方的IP
            String ip = dp.getAddress().getHostAddress();
            //getData()获取的是对方数据包的字节数组,要转换成字符串才能打印
            String data = new String(dp.getData(),0,dp.getLength());
            System.out.println(ip + ":::::::::" + data);
        }
    }
}

2 ,需求:使用 UDP 协议实现一个聊天程序,要求在同一个命令窗口显示发送的信息和接收的信息。


import java.io.*;
import java.net.*;
public class MyChat
{
    public static void main(String[] args) throws Exception {
        //启动接收线程和发送线程
        DatagramSocket sendSocket = new DatagramSocket(10019);
        DatagramSocket receiveSocket = new DatagramSocket(10002);
        new Thread(new Send(sendSocket)).start();
        new Thread(new Receive(receiveSocket)).start();
    }
}
//定义发送线程
class Send implements Runnable
{
    private DatagramSocket ds;
    public Send(DatagramSocket ds) {
        this.ds = ds;
    }
    public void run() {
        try
        {
            BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
            String line = null;
            while ((line = bufr.readLine()) != null)
            {
                if("886".equals(line))
                    break;
                byte[] b = line.getBytes();
                DatagramPacket dp = new 
                    DatagramPacket(b,b.length,InetAddress.getByName("JACK-PC"),10002);
                ds.send(dp);
            }
            ds.close();
        }
        catch (Exception e)
        {
            throw new RuntimeException("Send error,please try again");
        }
            
    }
}
//定义接受线程
class Receive implements Runnable
{
    private DatagramSocket ds;
    public Receive(DatagramSocket ds) {
        this.ds = ds;
    }
    public void run() {
        try
        {
            while (true)
            {
                byte[] b = new byte[1024];
                DatagramPacket dp = new DatagramPacket(b,b.length);
                ds.receive(dp);
                String ip = dp.getAddress().getHostAddress();
                String data = new String(dp.getData(),0,dp.getLength());
                System.out.println(ip + ":::::::::" + data);
            }
            
        }
        catch (Exception e)
        {
            throw new RuntimeException("Get errror");
        }
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值