Java网络编程

网络编程

问题

  • 如何定位
  • 定位后如何通信

要素

  • IP和端口号
  • 网络通信协议

IP

  • 127.0.0.1 :本机localhost
  • ip分类
    • ipv4/ipv6
      • ipv4 :127.0.0.1, 4个字节组成。
      • ipv6:128位。8个无符号整数 如 2020:0bb0:aaaa:2020:0bb0:aaaa:2020:0bb0
    • 公网,私网
      • 192.168.xx.xx专门给组织内部使用的
      • ABCD类地址

端口

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

  • 被规定0~65535

  • TCP,UDP:65532*2 tcp:80 udp:80, 单个协议端口号不能冲突

  • 端口分类(端口号不用刻意去记)

    • 公有端口

      • HTTP:80
      • HTTPS:443
      • FTP:21
      • Telent:23
    • 程序注册端口:1014~49151,分配用户或者程序

      • Tomcat:8080
      • MySQL:3306
      • Oracle:1512
    • 动态,私有:49152~65535

    • netstat -ano#查看所有的端口
      netstat -ano|findstr ""#查看制定的端口
      tasklist|findstr ""#查看指定端口的进程
      
      package com.wang.learnInternet;
      
      import java.net.InetSocketAddress;
      
      public class TestInetSocketAddress {
          public static void main(String[] args) {
              InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1", 8080);
      //        System.out.println(socketAddress);
              System.out.println(socketAddress.getAddress());
              System.out.println(socketAddress.getHostName());
              System.out.println(socketAddress.getPort());
          }
      }
      

TCP

  • 客户端
    1. 连接服务器socket
    2. 发送消息 IO流
  • 服务器
    1. 建立服务端口 ServerSocket
    2. 等待用户的连接 accept
    3. 接受用户消息 (用管道流)

客户端的代码:

package com.wang.learnTCP;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;

public class TcpClientDemo01 {
    public static void main(String[] args) {
        Socket socket = null;
        OutputStream outputStream = null;
        try {
            //1、获取服务器地址
            InetAddress serverIP = InetAddress.getByName("127.0.0.1");
            int port = 9999;
            //2.创建socket连接
            socket = new Socket(serverIP,port);
            //3.发送消息,IO流
            outputStream = socket.getOutputStream();

            outputStream.write("hello,world!这是我的第一个客户端,嘿嘿嘿嘿".getBytes(StandardCharsets.UTF_8));
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

服务器的代码

package com.wang.learnTCP;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class TcpServerDemo01 {
    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream inputStream = null;
        ByteArrayOutputStream byteArrayOutputStream = null;
        try  {
            //1、要有一个地址
            serverSocket = new ServerSocket(9999);
            //2.等待客户端连接过来
            while (true){
                socket = serverSocket.accept();
                //3.读取客户端消息
                inputStream = socket.getInputStream();
                //管道流
                byteArrayOutputStream = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                int len;
                while ((len=inputStream.read(buffer))!=-1){
                    byteArrayOutputStream.write(buffer,0,len);
                }
                System.out.println(byteArrayOutputStream.toString());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            if (byteArrayOutputStream != null) {
                try {
                    byteArrayOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (serverSocket != null) {
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

文件上传

客户端

package com.wang.learnTCP;

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

public class TcpClientDemo02 {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9000);
        //输出流
        OutputStream os = socket.getOutputStream();

        //文件流读取
        FileInputStream fis = new FileInputStream(new File("b.png"));
        //写出文件
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer))!=-1){
            os.write(buffer,0,len);
        }
        //通知服务器,我传完了
        socket.shutdownOutput();
        //确定接受完毕,关闭连接
        InputStream is = socket.getInputStream();
        //byte[],管道流
        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.toString());
        //关闭资源
        baos.close();
        is.close();
        fis.close();
        os.close();
        socket.close();
    }
}

服务器

package com.wang.learnTCP;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

public class TcpServerDemo02 {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(9000);
        //监听客户端的链接
        Socket socket = serverSocket.accept();//阻塞式监听,会一直等待客户端连接
        //获取输入流
        InputStream is = socket.getInputStream();
        //文件输出
        FileOutputStream fos = new FileOutputStream(new File("receive.jpg"));
        byte[] buffer = new byte[1024];
        int len;
        while ((len = is.read(buffer))!=-1){
            fos.write(buffer,0,len);
        }
        //通知客户端我已接受完毕
        OutputStream out = socket.getOutputStream();
        out.write("我已接受完毕,可以断开".getBytes(StandardCharsets.UTF_8));

        out.close();
        fos.close();
        is.close();
        socket.close();
        serverSocket.close();
    }
}

路径问题

文件开始创建时就要放好地方,以后不要乱挪动了,因为暂时不知道怎么配置路径

Tomcat

服务段

  • 自定义 S
  • Tomcat服务器 S

客户端

  • 自定义 C
  • 浏览器 B

UDP

发短信:不用连接,需要知道对方地址

发送端

package com.wang.learnUDP;

import java.io.IOException;
import java.net.*;
import java.nio.charset.StandardCharsets;

public class UdpClientDemo01 {
    public static void main(String[] args) throws IOException {
        //建立一个Socket
        DatagramSocket socket = new DatagramSocket();
        //发送给谁
        InetAddress localhost = InetAddress.getByName("localhost");
        int port = 9090;
        //建立一个包   发送的数据,数据的开始,长度,要发送的地址,端口
        String msg = "你好,世界!";
        DatagramPacket packet = new DatagramPacket(msg.getBytes(StandardCharsets.UTF_8),0,msg.getBytes(StandardCharsets.UTF_8).length,localhost,port);
        //发送包
        socket.send(packet);
        socket.close();
    }
}

接收端

package com.wang.learnUDP;

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

public class UdpServerDemo01 {
    public static void main(String[] args) throws Exception {
        //开放端口
        DatagramSocket socket = new DatagramSocket(9090);
        //接受数据
        byte[] buffer = new byte[1024];
        //接受
        DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);
        socket.receive(packet);//阻塞接受
        System.out.println(packet.getAddress().getHostAddress());
        System.out.println(new String(packet.getData(),0,packet.getLength()));
        socket.close();

    }
}

循环发送消息

package com.wang.chat;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;

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(StandardCharsets.UTF_8);//StandardCharsets.UTF_8
            DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress("localhost",6666));
            socket.send(packet);
            if(("bye".equals(data.trim()))){
                break;
            }
        }
        socket.close();
    }
}

循环接收消息

package com.wang.chat;

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

public class UDPReceiverDemo01 {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(6666);
        byte[] container = new byte[1024];
        while (true){
            //接受包裹
            DatagramPacket packet = new DatagramPacket(container, 0, container.length);
            socket.receive(packet);
            //断开连接
            byte[] data = packet.getData();
            //这里packet.getLength()很重要!!!如果不是packet的长度而是data数组的长度,那么接收到的数据会残留上一次的内容
            String receiveDate = new String(data, 0, packet.getLength()).trim();
            System.out.println(receiveDate);

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

两个人都可以是接收和发送方

package com.wang.chat;

import sun.nio.cs.ext.GBK;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;

public class TalkSend implements Runnable {
    DatagramSocket socket = null;
    BufferedReader reader = null;
    private String toIP;
    private int toPort;
    private int fromPort;

    public TalkSend(String toIP, int toPort, int fromPort) {
        this.toIP = toIP;
        this.toPort = toPort;
        this.fromPort = fromPort;
        try {
            socket = new DatagramSocket(fromPort);
            reader = new BufferedReader(new InputStreamReader(System.in));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        //准备数据,从控制台读取System.in
        while (true) {
            String data = null;
            try {
                data = reader.readLine();
                //必须要转换成字节
                byte[] datas = data.getBytes(StandardCharsets.UTF_8);//StandardCharsets.UTF_8
                DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress(this.toIP, this.toPort));
                socket.send(packet);
                if (("bye".equals(data.trim()))) {
                    break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        socket.close();
    }
}
package com.wang.chat;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;

public class TalkReceive implements Runnable{
    DatagramSocket socket = null;
    private int port;
    private String msgFrom;
    public TalkReceive(int port, String msgFrom) {
        this.msgFrom = msgFrom;
        this.port = port;
        try {
            socket = new DatagramSocket(port);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        //准备数据,从控制台读取System.in
        while (true) {
            try {
                byte[] container = new byte[1024];
                //接受包裹
                DatagramPacket packet = new DatagramPacket(container, 0, container.length);
                socket.receive(packet);
                //断开连接
                byte[] data = packet.getData();
                //这里packet.getLength()很重要!!!如果不是packet的长度而是data数组的长度,那么接收到的数据会残留上一次的内容
                String receiveDate = new String(data, 0, packet.getLength()).trim();
                System.out.println(msgFrom+": "+receiveDate);

                if("bye".equals(receiveDate)){
                    break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        socket.close();
    }
}
package com.wang.chat;

public class TalkStudent {
    //开启两个线程
    public static void main(String[] args) {
        new Thread(new TalkSend("localhost",9999,7777)).start();
        new Thread(new TalkReceive(8888,"老师")).start();
    }
}
package com.wang.chat;

public class TalkTeacher {
    public static void main(String[] args) {
        new Thread(new TalkSend("localhost",8888,5555)).start();
        new Thread(new TalkReceive(9999,"学生")).start();
    }
}

URL

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

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

基本属性

package com.wang.learnURL;

import java.net.MalformedURLException;
import java.net.URL;
//http://localhost:8080/wangyang/Security.txt
public class URLDemo01 {
    public static void main(String[] args) throws MalformedURLException {
        URL url = new URL("http://localhost:8080/helloworld/index.jsp?username=wang&password=123");
        System.out.println(url.getProtocol());
        System.out.println(url.getHost());
        System.out.println(url.getPort());
        System.out.println(url.getPath());//文件
        System.out.println(url.getFile());//文件全路径
        System.out.println(url.getQuery());//参数
    }
}

下载资源

package com.wang.learnURL;

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

public class URLDown {
    public static void main(String[] args) throws Exception {
//        URL url = new URL("http://localhost:8080/wangyang/Security.txt");
        URL url = new URL("https://p1.music.126.net/rxBbH4p-3rt8DMvaU5M8jw==/109951166567127803.jpg?param=130y130");
        //连接到资源,建立连接
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
        //下载
        InputStream inputStream = urlConnection.getInputStream();
//        FileOutputStream fos = new FileOutputStream("security.txt");
        FileOutputStream fos = new FileOutputStream("receive.jpg");
        byte[] buffer = new byte[1024];
        int len;
        while ((len = inputStream.read(buffer))!=-1){
            fos.write(buffer,0,len);
        }
        fos.close();
        inputStream.close();
        urlConnection.disconnect();//断开连接
    }
}

Tomcat

  • 环境变量设置

    • 新建CATALINA_HOME变量,值设为 Tomcat文件夹目录

    • path变量值添加

      %CATALINA_HOME%\bin
      
    • cmd输入 startup

    • 网页测试是否成功

      localhost:8080
      
  • 控制cmd窗口乱码,解决方法

    • conf文件夹->logging.properties文件->找到下列语句

    • java.util.logging.ConsoleHandler.encoding = UTF-8
      
    • 改成

      java.util.logging.ConsoleHandler.encoding = GBK
      
posted @ 2021-11-11 23:17  ddl战士  阅读(70)  评论(0)    收藏  举报