网络编程

网络通信要素: ip + 端口 + 网络通信协议

IP

ip地址:InetAddress

System.out.println(InetAddress.getByName("127.0.0.1"));     System.out.println(InetAddress.getByName("localhost"));
System.out.println(InetAddress.getLocalHost());
InetAddress baidu =InetAddress.getByName("www.baidu.com");
System.out.println(baidu);
System.out.println(baidu.getAddress());

端口

InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1", 8080);

端口表示计算机上的一个程序的进程;

  • 不同的进程有不同的端口号,用来区分软件

  • 范围0~65535

  • 端口分类

    • 公有端口 :0~1023

      HTTP:80, HTTPS:443, FTP:21, Telent:23

    • 程序注册端口:1024~49151。分配用户或程序

      Tomcat:8080, MySql:3306, Oracle:1521

    • 动态、私有:49152~65535

    • 常用命令

      netstat -ano #查看所有端口
      netstat -ano|findstr "7777" #查看指定的端口
      tasklist|findstr "7777" #查看指定端口的进程
      ctrl+shift+esc  #显示任务管理器
      

通信协议

TCP:用户传输协议,UDP:用户数据协议

TCP和UDP对比:

TCP:打电话

  • 连接,稳定

  • 三次握手,四次挥手

    a:听到我说话了吗
    b:我听到了
    a:好的,那来玩
    
    a:我要走了
    b:好,知道你要走了
    a:你真的要走了吗
    b:我真的要走了
    
  • 客户端、服务端

  • 传输完成,释放连接,效率低

UDP:发短信

  • 不连接,不稳定

  • 客户端、服务端没有明确界限

  • 不管有没有准备好,都可以发给你

TCP

服务端

  1. 建立服务的端口 ServerSocket

  2. 等待用户的连接 accept

  3. 接收用户的消息

package com.my.ip;

import java.io.ByteArrayOutputStream;
import java.io.Closeable;
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) {
        ServerSocket serverSocket = null;
        Socket accept = null;
        InputStream in = null;
        ByteArrayOutputStream out = null;
        try {
            //创建服务端
             serverSocket = new ServerSocket(7777);
             while(true){
                 //等待客户端连接
                 accept = serverSocket.accept();
                 //获取客户端的消息
                 in = accept.getInputStream();
                 //管道流
                 out = new ByteArrayOutputStream();
                 byte[] buffer = new byte[1024];
                 int len;
                 while((len=in.read(buffer)) != -1) {
                     out.write(buffer,0,len);
                 }
                 System.out.println(out.toString());
             }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            myClose(out);
            myClose(in);
            myClose(accept);
            myClose(serverSocket);
        }
    }

    public static void myClose(Closeable closeable){
        if (closeable != null) {
            try {
                closeable.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

客户端

  1. 连接服务器 Socket
  2. 发送消息
package com.my.ip;

import java.io.Closeable;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

//客户端
public class TcpClient {
    public static void main(String[] args) {
        Socket socket = null;
        OutputStream out = null;
        try {
            //建立客户端,要知道服务端的ip,端口
            socket = new Socket("127.0.0.1",7777);
            //发送消息
            out = socket.getOutputStream();
            out.write("hello hello!".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            myClose(out);
            myClose(socket);
        }
    }

    public static void myClose(Closeable closeable){
        if (closeable != null) {
            try {
                closeable.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

TCP上传文件

package com.my.ip;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

//tcp文件上传服务端
public class TcpFileServer {
    public static void main(String[] args) throws IOException {
        //建立服务端
        ServerSocket serverSocket = new ServerSocket(7777);
        //等待客户端连接
        Socket socket = serverSocket.accept();
        //接收数据
        InputStream is = socket.getInputStream();
        FileOutputStream fos = new FileOutputStream(new File("接收.jpg"));
        int len;
        byte[] buffer = new byte[1024];
        while ((len = is.read(buffer)) != -1) {
            //将数据写道文件中
            fos.write(buffer,0,len);
        }

        //向客户端发送消息
        OutputStream os = socket.getOutputStream();
        os.write("我收到文件了,你可以断开了".getBytes());

        //关闭
        os.close();
        fos.close();
        is.close();
        socket.close();
        serverSocket.close();
    }
}

package com.my.ip;

import java.io.*;
import java.net.Socket;

//tcp文件上传客户端
public class TcpFileClient {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1",7777);
        OutputStream os = socket.getOutputStream();
        //读文件
        FileInputStream fis = new FileInputStream(new File("a3.jpg"));
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer)) != -1) {
            //写文件
            os.write(buffer,0,len);
        }
        //通知服务器,我已经结束了
        socket.shutdownOutput();

        InputStream is = socket.getInputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer2 = new byte[1024];
        int len2;
        while ((len2 = is.read(buffer2)) != -1) {
            baos.write(buffer2,0,len2);
        }
        System.out.println(baos);

        is.close();
        baos.close();
        fis.close();
        os.close();
        socket.close();
    }
}

Tomcat

服务端

  • 自定义 S
  • Tomcat服务器 S:Java后台开发

客户端

  • 自定义 C
  • 浏览器 B

Tomcat启动控制台乱码:

解决方法:windows下默认编码位GBK

在"\apache-tomcat-**\conf\logging.properties"中

将java.util.logging.ConsoleHandler.encoding = UTF-8改为

java.util.logging.ConsoleHandler.encoding = GBK

UDP

聊天

package com.my.ip.udp1;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.*;

//发消息
public class UdpSend {
    public static void main(String[] args) throws Exception {
        int sendPort = 7777;
        DatagramSocket socket = new DatagramSocket(sendPort);

        //准备数据,从控制台读取
        String recIp = "localhost";
        int recPort = 7788;
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        while (true){
            String data = reader.readLine();
            byte[] bytes = data.getBytes();
            DatagramPacket datagramPacket = 
            			new DatagramPacket(bytes,0,bytes.length,new InetSocketAddress(recIp,recPort));
            socket.send(datagramPacket);

            if ("bye".equals(data)) {
                break;
            }
        }
        reader.close();
        socket.close();
    }
}

package com.my.ip.udp1;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

//收消息
public class UdpRecevie {
    public static void main(String[] args) throws Exception {
        int recPort = 7788;
        DatagramSocket socket = new DatagramSocket(recPort);

        while(true){
            byte[] bytes = new byte[1024];
            DatagramPacket packet = new DatagramPacket(bytes,0,bytes.length);
            socket.receive(packet);//阻塞式接收包裹

            byte[] data = packet.getData();
            String s = new String(data).trim();
            System.out.println(packet.getPort()+"说:"+s);

            if ("bye".equals(s)) {
                break;
            }
        }

        socket.close();

    }
}

互相聊天

package com.my.ip.udp2;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

//发送
public class UdpSend implements Runnable{

    int sendPort;
    String recIp;
    int recPort;
    DatagramSocket socket;
    BufferedReader reader;

    public UdpSend(int sendPort, String recIp, int recPort) {
        this.sendPort = sendPort;
        this.recIp = recIp;
        this.recPort = recPort;

        try {
            socket = new DatagramSocket(sendPort);
            //准备数据,从控制台读取
            reader = new BufferedReader(new InputStreamReader(System.in));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        try{
            InetSocketAddress address = new InetSocketAddress(recIp, recPort);
            while (true){
                String data = reader.readLine();
                byte[] bytes = data.getBytes();
                DatagramPacket datagramPacket = new DatagramPacket(bytes,0,bytes.length,address);
                socket.send(datagramPacket);

                if ("bye".equals(data)) {
                    break;
                }
            }
            reader.close();
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

package com.my.ip.udp2;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

//接收
public class UdpRecevie implements Runnable{

    int recPort;
    DatagramSocket socket;

    public UdpRecevie(int recPort) {
        this.recPort = recPort;

        try {
            socket = new DatagramSocket(recPort);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        while(true){
            byte[] bytes = new byte[1024];
            DatagramPacket packet = new DatagramPacket(bytes,0,bytes.length);
            try {
                socket.receive(packet);//阻塞式接收包裹
            } catch (IOException e) {
                e.printStackTrace();
            }

            byte[] data = packet.getData();
            String s = new String(data).trim();
            System.out.println(packet.getPort()+"说:"+s);

            if ("bye".equals(s)) {
                break;
            }
        }

        socket.close();
    }
}

A和B互相聊天

package com.my.ip.udp2;

public class TalkA {
    public static void main(String[] args) {
        //A:接收端口7777,发送端口5555
        new Thread(new UdpRecevie(7777)).start();
        new Thread(new UdpSend(5555,"localhost",7788)).start();
    }
}

package com.my.ip.udp2;

public class TalkB {
    public static void main(String[] args) {
        //B:接收端口7788,发送端口6666
        new Thread(new UdpRecevie(7788)).start();
        new Thread(new UdpSend(6666,"localhost",7777)).start();
    }
}

结果


URL

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

协议://ip:port/项目名/资源
如:http:www.baidu.com,  https://www.bilibili.com/video/BV1LJ411z7vY?p=12

下载

package com.my.ip.url;


import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class UrlDownload {
    public static void main(String[] args) throws Exception {

            URL url = new URL("https://i0.hdslb.com/bfs/static/manga/artifact/statistics/baidu.js");

            System.out.println(url.getProtocol());//协议 https
            System.out.println(url.getHost());//主机 i0.hdslb.com
            System.out.println(url.getPath());//全路径 /bfs/static/manga/artifact/statistics/baidu.js
            System.out.println(url.getPort());//端口 -1
            System.out.println(url.getFile());//文件 /bfs/static/manga/artifact/statistics/baidu.js
            System.out.println(url.getQuery());//参数 null

            HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
            InputStream stream = urlConnection.getInputStream();

            FileOutputStream fos = new FileOutputStream("baidu.js");
            int len;
            byte[] buffer = new byte[1024];
            while ((len = stream.read(buffer)) != -1) {
                fos.write(buffer,0,len);
            }
            fos.close();
            stream.close();
            urlConnection.disconnect();//断开连接
    }
}

posted @ 2021-05-20 18:13  快乐的额  阅读(93)  评论(0)    收藏  举报