Java网络编程

1.1 URL及其应用

URL(Uniform Resource Locator)中文名为统一资源定位符,有时也被俗称为网页地址。表示为互联网上的资源,如网页或者FTP地址。

URL 解析:
协议为(protocol):http
主机为(host:port):www.fuxian.org
端口号为(port): 80 ,以上URL实例并未指定端口,因为 HTTP 协议默认的端口号为 80。
文件路径为(path):/index.html
请求参数(query):language=cn
定位位置(fragment):j2se,定位到网页中 id 属性为 j2se 的 HTML 元素位置 。

构造方法:

 

 

 常用方法:

 

 

 

package com.fuxian.url;

import java.net.MalformedURLException;
import java.net.URL;

public class TestURL {
    public static void main(String[] args) {
        try {
            URL url = new URL("https://www.cnblogs.com/LEPENGYANG/p/15060223.html");
            System.out.println("URL为:" + url.toString());
            System.out.println("协议为:" + url.getProtocol());
            System.out.println("验证信息为:" + url.getAuthority());
            System.out.println("文件名及请求参数为:" + url.getFile());
            System.out.println("主机名:" + url.getHost());
            System.out.println("路径为:" + url.getPath());
            System.out.println("端口为:" + url.getPort());
            System.out.println("默认端口为:" + url.getDefaultPort());
            System.out.println("请求参数为:" + url.getQuery());
            System.out.println("定位位置为:" + url.getRef());
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }
}

1.2 InetAddress及其应用

InetAddress在java.net包下,主要用于IP地址和域名

常用方法:

 

 

 

 

package com.fuxian.url;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class TestInetAddress {
    public static void main(String[] args) {
        try {
            InetAddress byAddress = InetAddress.getByName("www.fuxian.org");
            System.out.println("博客域名:" + byAddress.getHostName());
            System.out.println("博客的IP地址:" + byAddress.getHostAddress());

            InetAddress localHost = InetAddress.getLocalHost();
            System.out.println("本地IP地址:" + localHost.getHostName());
            System.out.println("本地IP地址:" + localHost.getHostAddress());
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }
}

1.3 Socket通信-单向通信

TCP 是传输控制协议的缩写,它保障了两个应用程序之间的可靠通信。通常用于互联网协议,被称 TCP/IP


Socket套接字使用TCP提供了两台计算机之间的通信机制。 客户端程序创建一个套接字,并尝试连接服务器的套接字。


当连接建立时,服务器会创建一个 Socket 对象。客户端和服务器现在可以通过对 Socket 对象的写入和读取来进行通信


java.net.Socket 类代表一个套接字,并且 java.net.ServerSocket 类为服务器程序提供了一种来监听客户端,并与他们建立连接的机制。

服务器端建立步骤
    1:建立服务器端套接字,指定监听端口
    2:监听,等待客户端请求,并愿意接受连接
    3:获取Socket的输出流,并使用缓冲流进行包装
    4:向客户端发送反馈信息
    5:关闭流及Socket连接

客户端建立步骤:
    1:创建一个Socket对象
    2:获取Socket的输入流,并使用缓冲流进行包装
    3接收服务器端发送的信息
    4:关闭流及Socket连接

1.4 Socket通信-多向通信

服务器端建立步骤:
    1:建立服务器端套接字,指定监听端口
    2:监听,等待客户端请求,并愿意接受连接
    3:获取Socket的输入流,并使用缓冲流进行包装
    4:获取Socket的输出流,并使用缓冲流进行包装
    5:获取客户端发送的数据
    6:向客户端发送反馈信息
    7:关闭流及Socket连接

package com.fuxian.url;

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

public class DoubleServer {
    public static void main(String[] args) {
        Socket socket = null;
        BufferedWriter bufferedWriter = null;
        BufferedReader bufferedReader = null;
        try {
            //1.建立服务器端套接字,指定监听端口
            ServerSocket serverSocket = new ServerSocket(8888);
            System.out.println("服务器端启动成功了!");
            //2.监听,等待客户端请求,并愿意接受连接
            socket = serverSocket.accept();
            //添加内容:从输入流中读取客户端发送过来的数据
            bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String line = bufferedReader.readLine();
            System.out.println("从客户端发送过来的数据:" + line);
            //3.socket的输出流,并使用缓冲流进行包装
            bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            //4.向客户端发送反馈信息
            bufferedWriter.write("这是服务器发送的数据,你收到了吗?");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //5:关闭流及Socket连接
            try {
                if (bufferedWriter != null)
                    bufferedWriter.close();
                if (socket != null)
                    socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

 

客户端建立步骤:
    1:创建一个Socket对象
    2:获取Socket的输出流,并使用缓冲流进行包装
    3:获取Socket的输入流,并使用缓冲流进行包装
    4:向服务器端发送数据
    5:接收服务器端发送的信息
    6:关闭流及Socket连接

 

package com.fuxian.url;

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

public class DoubleClient {
    public static void main(String[] args) {
        Socket socket = null;
        BufferedReader bufferedReader = null;
        BufferedWriter bufferedWriter = null;
        try {
            //1.创建一个Socket对象
            socket = new Socket("127.0.0.1", 8888);
            //添加内容:向服务器发送一句话
            bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            bufferedWriter.write("这是客户端向服务器端发送的数据\n");
            bufferedWriter.flush();
            bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //2.获取Socket的输入流,并使用缓冲流进行包装
            //3.接受服务器端发送的信息
            String line = bufferedReader.readLine();
            System.out.println(line);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4.关闭流及Socket连接
            try {
                if (bufferedReader != null)
                    bufferedReader.close();
                if (socket != null)
                    socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

 

1.5 Socket通信-多线程下的多客户端通信

服务器端建立步骤:
    1:建立服务器端套接字,指定监听端口
    2:在死循环中开启监听,等待客户端请求,并愿意接受连接
    3:开启线程对Socket进行处理    
        a:获取Socket的输入流,并使用缓冲流进行包装
        b:获取Socket的输出流,并使用缓冲流进行包装
        c:获取客户端发送的数据
        d:向客户端发送反馈信息
        e:关闭流及Socket连接

package com.jh.socketPackage;

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

public class ThreadServer {
    public static void main(String[] args) {
        //1.建立服务器端套接字,指定监听端口
        ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket(8888);
            System.out.println("服务器启动成功了!");
        } catch (IOException e) {
            System.err.println("服务器监听失败!");
        }
        while (true) {
            try {
                Socket socket = serverSocket.accept();
                //开启线程处理这个socket
                Task task = new Task(socket);
                task.start();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
package com.jh.socketPackage;

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

public class Task extends Thread {
    private Socket socket;

    public Task() {
    }

    public Task(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        //处理socket套接字
        BufferedReader bufferedReader = null;
        BufferedWriter bufferedWriter = null;
        try {
            System.out.println("有客户端连接了!");
            //添加内容:从输入流中读取客户端发送过来的数据
            bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String line = bufferedReader.readLine();
            System.out.println("客户端发送过来的数据:" + line);
            //3.获取Socket的输出流,并使用缓冲流进行包装
            bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            bufferedWriter.write("这是服务器发送的数据,你收到了吗?");
            bufferedWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (socket != null)
                    socket.close();
                if (bufferedReader != null)
                    bufferedReader.close();
                if (bufferedWriter != null)
                    bufferedWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}


客户端建立步骤:
    将以下步骤放入线程的run方法中处理
        1:创建一个Socket对象
        2:获取Socket的输出流,并使用缓冲流进行包装
        3:获取Socket的输入流,并使用缓冲流进行包装
        4:向服务器端发送数据
        5:接收服务器端发送的信息
        6:关闭流及Socket连接

package com.jh.socketPackage;

import sun.security.mscapi.CPublicKey;

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

public class DoubleClient {
    public static void main(String[] args) {
        long start = System.currentTimeMillis(); //起始的毫秒数
//        client("1");
//        client("2");
//        client("3");
//        client("4");
//        client("5");
        new ThreadClient("1").start();
        new ThreadClient("2").start();
        new ThreadClient("3").start();
        new ThreadClient("4").start();
        new ThreadClient("5").start();
        long end = System.currentTimeMillis(); //结束的毫秒数
        System.out.println(end-start);
    }

    public static void client(String name) {
        Socket socket = null;
        BufferedWriter bufferedWriter = null;
        BufferedReader bufferedReader = null;
        try {
            //1.创建一个Socket对象
            socket = new Socket("127.0.0.1", 8888);
            bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            //2.获取Socket的输入流,并使用缓冲区进行包装
            bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //添加内容:向服务器发送数据
            bufferedWriter.write("这是"+name+"客户端向服务器端发送的数据\n");
            bufferedWriter.flush();
            //3.接受服务器端发送的信息
            String line = bufferedReader.readLine();
            System.out.println(line);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (socket != null)
                    socket.close();
                if (bufferedReader != null)
                    bufferedReader.close();
                if (bufferedWriter != null)
                    bufferedWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
package com.jh.socketPackage;

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

public class ThreadClient extends Thread {
    private String name;

    public ThreadClient() {
    }

    public ThreadClient(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        client(name);
    }

    public void client(String name) {
        Socket socket = null;
        BufferedWriter bufferedWriter = null;
        BufferedReader bufferedReader = null;
        try {
            //1.创建一个Socket对象
            socket = new Socket("127.0.0.1", 8888);
            bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            //2.获取Socket的输入流,并使用缓冲区进行包装
            bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //添加内容:向服务器发送数据
            bufferedWriter.write("这是" + name + "客户端向服务器端发送的数据\n");
            bufferedWriter.flush();
            //3.接受服务器端发送的信息
            String line = bufferedReader.readLine();
            System.out.println(line);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (socket != null)
                    socket.close();
                if (bufferedReader != null)
                    bufferedReader.close();
                if (bufferedWriter != null)
                    bufferedWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

1.6 UDP通信

服务器端建立步骤:
    1.创建socket服务,并监听端口
 2.创建数据包,用来接收数据
 3.用socket接收数据到数据包中
 4.从数据包中取出数据
 5.关闭资源

package com.jh.socketPackage;

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

public class Server {
    public static void main(String[] args) {
        DatagramSocket datagramSocket = null;
        try {
            //1.创建服务器socket,并监听端口
            datagramSocket = new DatagramSocket(8888);
            while (true) {
                byte[] bytes = new byte[1024];
                //2.创建数据包,用来接收数据
                DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
                //3.用socket接受数据到数据包中
                datagramSocket.receive(datagramPacket);
                //4.读取数据
                String s = new String(bytes, 0, bytes.length);
                System.out.println("消息是:" + s);
                if ("886".equals(s))
                    break;
            }
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            datagramSocket.close();
        }
    }
}

 


客户端建立步骤:
    1.创建socket服务
    2.创建数据包
    3.将数据封装到数据包中,添加ip和端口以及数据
    4.发送
    5.关闭资源

package com.jh.socketPackage;

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

public class Client {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        DatagramSocket datagramSocket = null;
        try {
            //1.创建客户端socket
            datagramSocket = new DatagramSocket();
            while (true) {
                System.out.println("请输入要发送的信息:");
                String line = scanner.nextLine();
                //2.创建客户端发送数据包
                byte[] bytes = line.getBytes();
                //3.将数据封装到数据包中,添加ip和端口以及数据
                DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("localhost"), 8888);
                //4.发送数据包
                datagramSocket.send(datagramPacket);
                //结束发送循环
                if ("886".equals(line))
                    break;
            }
        } catch (SocketException | UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            datagramSocket.close();
        }
    }
}

 

1.7 作业练习

1:编写一个基于TCP通信的程序,效果如图所示:

 

 

 

 

满足以下几点要求

A:服务器端具备多线程处理能力

B:客户端具备多线程发送能力

C:服务器端和客户端都具备从控制台接收输入的能力

C:服务器端和客户端都具备无限次数的双向通信能力

D:当服务器端或客户端发送”end”时通信结束

 

package project1;

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

public class ThreadServer {

    public static void main(String[] args) throws IOException {
//        1:建立服务器端套接字,指定监听端口
        ServerSocket serverSocket = new ServerSocket(8888);
        System.out.println("服务器端启动成功了!");

        while (true) {
            Socket socket = serverSocket.accept();
            // 开启线程处理这个socket
            Task task = new Task(socket);
            task.start();
        }

    }

}
package project1;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

public class Task extends Thread {
    private Socket socket;

    public Task() {

    }

    public Task(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {

        // 处理socket套接字
        BufferedWriter bw = null;
        BufferedReader br = null;
        BufferedReader consoleIn = null;
        try {
            System.out.println("有客户端连接了!");
            // 添加内容:从输入流中读取客户端发送过来的数据
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            // 3:获取Socket的输出流,并使用缓冲流进行包装
            bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

            // 控制台输入流-->控制台向我发送的内容/控制台输入的内容
            consoleIn = new BufferedReader(new InputStreamReader(System.in));
            while (true) {
                // 从输入流中读取内容
                String fromClien = br.readLine();
                System.out.println("客户端:" + fromClien);

                // 4:向客户端发送反馈信息
                System.out.print("服务器端:");
                String toClient = consoleIn.readLine();
                if (toClient.contains("end") || fromClien.contains("end")) {
                    break;
                }

                bw.write(toClient + "\n");
                bw.flush();

            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 5:关闭流及Socket连接
            // a:关闭流
            try {
                if (bw != null)
                    bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            // b:关闭Socket
            try {
                if (socket != null)
                    socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
package project1;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class ThreadClient extends Thread {
    private String name;

    public ThreadClient(String name) {
        super();
        this.name = name;
    }

    @Override
    public void run() {
        client(name);
    }

    public void client(String name) {
        Socket socket = null;
        BufferedReader br = null;
        BufferedWriter bw = null;
        BufferedReader consoleIn = null;
        try {
            // 1:创建一个Socket对象
            socket = new Socket("127.0.0.1", 8888);

            // 添加内容:向服务发送一句话
            bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            // 2:获取Socket的输入流,并使用缓冲流进行包装
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            // 控制台输入流-->控制台向我发送的内容/控制台输入的内容
            consoleIn = new BufferedReader(new InputStreamReader(System.in));
            while (true) {

                // 添加内容:向服务器端发送数据
                System.out.print("客户端:");
                String toServer = consoleIn.readLine();
                if (toServer.contains("end")) {
                    break;
                }
                bw.write(toServer + "\n");
                bw.flush();

                // 3接收服务器端发送的信息
                String fromServer = br.readLine();
                System.out.println("服务器端:" + fromServer);
            }

        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 4:关闭流及Socket连接
            // a:关闭流
            try {
                if (br != null)
                    br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            // b:关闭Socket
            try {
                if (socket != null)
                    socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
package project1;

public class TestClient {

    public static void main(String[] args) {
        new ThreadClient("1").start();
    }
}

 



 

 

posted @ 2021-07-30 12:38  蔡地像徐坤  阅读(61)  评论(0)    收藏  举报