java网络编程TCP、UDP、URL

计算机网络概念

计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统网络管理软件网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。

  • 网络编程的目的:

    • 传播交流信息。
    • 数据交换、通信。
  • 网络通信要素:

    • 通信双方的地址:IP和端口号

    • 网络通信协议

  • 网络编程的主要问题:

    • 如何准确定位到网络上的一台或多台主机?
    • 找到主机之后如何进行通信?

IP

  • 网络中标识主机。

    • 分为32位(IPV4)和128位(IPV6)。
    • 以点分形式体现。“192.168.2.6”
    • 分类:以二进制的前8位进行区分
    A类:0 ~ 127.255.255.255
    B类:128 ~ 191.255.255.255
    C类:192 ~ 223.255.255.255
    D类:224 ~ 239.255.255.255
    E类:240 ~ 255.255.255.255
    
    网络号	1字节	主机号	3字节	A类
    网络号	2字节	主机号	2字节	B类
    网络号	3字节	主机号	1字节	C类
    

InetAddress类的使用

/**
 * 测试IP
 */
public class InetAddressDemo {
    public static void main(String[] args) {
        try {
            //查询本机地址
            InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
            System.out.println(inetAddress1);
            InetAddress inetAddress3 = InetAddress.getByName("localhost");
            System.out.println(inetAddress3);
            InetAddress inetAddress4 = InetAddress.getLocalHost();
            System.out.println(inetAddress4);
            //查询网站ip地址
            InetAddress inetAddress2 = InetAddress.getByName("www.baidu.com");
            System.out.println(inetAddress2);
        } catch (UnknownHostException e) {
            throw new RuntimeException(e);
        }
    }
}

端口(区分进程)

  • 处理网络数据的进程号
  • 端口号:2字节(0~65532)

端口分类

  • 共有端口0-1023
    HTTP : 80

    HTTPS :443
    FTP : 21
    Telet : 23

  • 程序注册端口:1024-49151,分配给用户或者程序
    Tomcat:8080
    Mysql:3306
    Oracle:1521

  • 动态、私有:49152-65535

CMD查看端口

netstat -ano #查看所有端口
netstat -ano  | findstr "5900" #查看指定的端口
tasklist | findstr "8696" #查看指定端口的进程
Ctrl + Shift + ESC #打开任务管理器快捷键

InetSocketAddress的使用

public class InetSocketAddressDemo {
    public static void main(String[] args) {
        InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1",8080);
        System.out.println(inetSocketAddress.getAddress());
        System.out.println(inetSocketAddress.getHostName()); 
        System.out.println(inetSocketAddress.getPort());
    }
}

通讯协议

网络通讯协议:是指通信双方对数据传送控制的一种约定。定义了速率 、传输码率、代码结构、传输控制等。

  • 最常见的网络通信协议:TCP/IP协议簇

    • TCP:传输控制协议。
    • IP:网间协议。
    • UDP:数据报协议。
  • TCP和UDP的区别:

    • TCP:是一种面向连接的传输协议,提供高可靠通信(数据无丢失,数据无误,数据无失序)。

      使用场景:对传输质量要求较高,传输大量数据的通信。

    • UDP:用户数据报协议,是不可靠的无连接协议。

      使用场景:1.传输小尺寸数据;2.应答困难的网络中(无线网络);3.QQ点对点的文件传输和音视频传输;4.网络电话、流媒体;5.广播、组播。

    • 共同点:

      同为传输层协议。

    • 不同点:

      TCP:面向有连接,可靠(保证数据可靠<数据无失序、无重复、无丢失到达>)。

      UDP:面向无连接,不保证数据可靠。

TCP

  • 客户端

    1. 连接服务器Socket
    2. 发送消息
  • 服务器

    1. 建立服务端口ServerSocket
    2. 等待用户的连接 accept()
    3. 接收用户的消息

客户端与服务器通讯实例:

/**
 * 客户端
 */
public class TcpClientDemo01 {

    public static void main(String[] args) throws Exception{
        Socket socket = null;
        OutputStream os = null;
        //要知道服务器地址
        try {
            InetAddress serverIp = InetAddress.getByName("localhost");
            int port = 9999;
            //2.创建连接
            socket = new Socket(serverIp,port);
            //3.发生消息 IO流
            os = socket.getOutputStream();
            os.write("你好,服务器".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (os != null) {
                os.close();
            }
            if (socket != null) {
                socket.close();
            }
        }
    }
}
/**
 * 服务器端
 */
public class TcpServerDemo01 {
    public static void main(String[] args) throws Exception {
        ServerSocket serverSocket = null;
        Socket accept = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;
        try {
            //1. 我得有一个地址
            serverSocket = new ServerSocket(9999);
            //2.等待客户端连接过来
            accept = serverSocket.accept();
            //3.读取客户端消息
            is = accept.getInputStream();

        /*byte[] buf = new byte[1024];
        int len;
        while ((len = is.read(buf)) != -1 ){
            String s = new String(buf, 0, len);
            System.out.println(s);
        }*/

            //管道流
            baos = new ByteArrayOutputStream();
            byte[] buff = new byte[1024];
            int len = -1;

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

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (baos != null) {
                baos.close();
            }
            if (is != null) {
                is.close();
            }
            if (accept != null) {
                accept.close();
            }
            if (serverSocket != null) {
                serverSocket.close();
            }
        }
    }
}

文件上传实例

/**
 * 客户端上传文件
 */
public class TcpClientDemo02 {
    public static void main(String[] args) throws Exception {
        //1.创建一个socket连接
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
        //2.创建一个输出流
        OutputStream os = socket.getOutputStream();
        //3.读取文件
        FileInputStream fis = new FileInputStream(new File("雪山.jpg"));
        //4.写出文件
        byte[] buf = new byte[1024];
        int len = 0;
        while ((len=fis.read(buf))!=-1){
            os.write(buf,0,len);
        }
        //5.通知服务器,我已经上传结束
        socket.shutdownOutput();
        //6.确定服务器接收完毕,才能断开连接
        InputStream is = socket.getInputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buf2 = new byte[1024];
        int len2 = 0;
        while ((len2=is.read(buf2))!=-1){
            baos.write(buf2,0,len2);
        }
        System.out.println(baos.toString());
        //7.关闭资源
        baos.close();
        is.close();
        fis.close();
        os.close();
        socket.close();
    }
}
/**
 * 服务器接收文件
 */
public class TcpServerDemo02 {
    public static void main(String[] args) throws Exception {
        //1.创建服务端口
        ServerSocket serverSocket = new ServerSocket(9000);
        //2.监听客户端连接
        Socket socket = serverSocket.accept();//阻塞式监听,会一直等待客户端连接
        //3.获取输入流
        InputStream is = socket.getInputStream();
        //4.文件输出
        FileOutputStream fos = new FileOutputStream(new File("receive.jpg"));
        byte[] buf = new byte[1024];
        int len = 0;
        while ((len=is.read(buf))!=-1){
            fos.write(buf,0,len);
        }
        //5.通知客户端接收完毕
        OutputStream os = socket.getOutputStream();
        os.write("我接收完毕,可以断开连接了".getBytes());
        //6.关闭资源
        os.close();
        fos.close();
        is.close();
        socket.close();
        serverSocket.close();
    }
}

UDP

UDP通讯实例

//UDP通讯不需要连接服务器
//发送端
public class UdpClientDemo01 {
    public static void main(String[] args) throws Exception {
        //1.建立一个Socket
        DatagramSocket socket = new DatagramSocket();
        //2.建包
        String msg = "hello!server!";
        //服务器地址
        InetAddress localhost = InetAddress.getByName("localhost");
        int port = 9090;
        //数据、数据的长度起始、要发送给谁
        DatagramPacket dp = new DatagramPacket(msg.getBytes(StandardCharsets.UTF_8), 0, msg.getBytes().length, localhost, port);

        //3.发送包
        socket.send(dp);
        //4.关闭资源
        socket.close();
    }
}
//接收端
//等待客户端的连接
public class UdpServerDemo01 {
    public static void main(String[] args) throws Exception{
        //1.开放端口
        DatagramSocket socket = new DatagramSocket(9090);
        //2.接收数据包
        byte[] buf = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buf, 0, buf.length);
        socket.receive(packet); //阻塞式接收数据

        System.out.println(new String(packet.getData()));
        System.out.println(packet.getAddress().getHostAddress());
        //3.关闭连接
        socket.close();
    }
}

UDP实现循环发送消息

/**
 * 发送者
 */
public class UdpSenderDemo01 {
    public static void main(String[] args) throws Exception{
        DatagramSocket socket = new DatagramSocket(8888);
        //准备数据:控制台读取System.in
        //字符缓冲流
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        while (true){
            String data = reader.readLine();
            byte[] datas = data.getBytes();
            DatagramPacket packet = new DatagramPacket(datas,0,data.length(),new InetSocketAddress("localhost",6666));
            socket.send(packet);
            if (data.equals("bye")){
                break;
            }
        }
        socket.close();
    }
}
/**
 * 接收者
 */
public class UdpReceiveDemo01 {
    public static void main(String[] args) throws Exception{
        DatagramSocket socket = new DatagramSocket(6666);
        while (true){
            //准备接收包裹
            byte[] container = new byte[1024];
            DatagramPacket packet = new DatagramPacket(container,0,container.length);
            socket.receive(packet); //阻塞式接收包裹
            //断开连接
            byte[] data = packet.getData();
            String receiveData = new String(data, 0, packet.getLength());
            System.out.println(receiveData);
            if (receiveData.equals("bye")){
                break;
            }
        }
        socket.close();
    }
}

UDP实现在线咨询(双方均可发送、接收消息)

/**
*发送消息类
*/
public class TalkSend implements Runnable{
    DatagramSocket socket = null;
    BufferedReader reader = null;

    private int fromPort;
    private String toIP;
    private int toPort;

    public TalkSend(int fromPort, String toIP, int toPort) {

        this.fromPort = fromPort;
        this.toIP = toIP;
        this.toPort = toPort;

        try {
            socket = new DatagramSocket(fromPort);
            reader = new BufferedReader(new InputStreamReader(System.in));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public TalkSend() {

    }

    @Override
    public void run() {
        while (true){
            String data = null;
            try {
                data = reader.readLine();
                byte[] datas = data.getBytes();
                DatagramPacket packet = new DatagramPacket(datas,0,data.length(),new InetSocketAddress(this.toIP,this.toPort));
                socket.send(packet);
                if (data.equals("bye")){
                    break;
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        socket.close();
    }
}
/**
 *接收消息类
 */
public class TalkReceive implements Runnable {
    DatagramSocket socket = null;
    private int port;
    private String msgFrom;

    public TalkReceive(int port,String msgFrom) {
        this.port = port;
        this.msgFrom = msgFrom;
        try {
            socket = new DatagramSocket(port);
        } catch (SocketException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void run() {
        while (true){
            try {
                //准备接收包裹
                byte[] container = new byte[1024];
                DatagramPacket packet = new DatagramPacket(container,0,container.length);
                socket.receive(packet); //阻塞式接收包裹
                //断开连接
                byte[] data = packet.getData();
                String receiveData = new String(data, 0, packet.getLength());
                System.out.println(msgFrom+":"+receiveData);
                if (receiveData.equals("bye")){
                    break;
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        socket.close();
    }
}
/**
 * 学生端
 */
public class TalkStudent {
    public static void main(String[] args) {
        //开启两个线程
        new Thread(new TalkSend(7777,"localhost",9999)).start();
        new Thread(new TalkReceive(8888,"老师")).start();
    }
}
/**
 * 教师端
 */
public class TalkTeacher {
    public static void main(String[] args) {
        //开启两个线程
        new Thread(new TalkSend(5555,"localhost",8888)).start();
        new Thread(new TalkReceive(9999,"学生")).start();
    }
}

URL

URL:统一资源定位符,定位互联网上的某一资源。

  • 协议:// ip地址: 端口/项目名/资源

URL类的使用

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

URL实现下载文件

public class URLDownDemo {
    public static void main(String[] args) throws Exception {
        //1.下载地址
        URL url = new URL("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fblog%2F202105%2F19%2F20210519222344_nqchs.jpg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1659510068&t=4949cc78685e445710aa14a4fe171d1d");
        //2.连接资源 http
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

        InputStream inputStream = urlConnection.getInputStream();
        FileOutputStream fos = new FileOutputStream("leigexi.png");

        byte[] buf = new byte[1024];
        int len = 0;
        while ((len=inputStream.read(buf))!=-1){
            fos.write(buf,0,len);
        }
        fos.close();
        inputStream.close();
        urlConnection.disconnect();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值