Fork me on GitHub

JavaSE| 网络编程

 

URL

URI(Uniform resource identifier):表示一个统一资源标识符 (URI) 引用,用来唯一的标识一个资源。

URL(Uniform Resource Locator):类 URL 代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。URI不能用于定位任何资源,它的唯一作用是解析,而URL则包含一个可打开到达该资源的输入流。 URL的基本结构由5部分组成:

<传输协议>://<主机名>:<端口号>/<文件名>#片段名
<传输协议>://<主机名>:<端口号>/<文件名>?参数列表

其中#片段名:即锚点,例如看小说,直接定位到章节

例如:http://java.sun.com/index.html#chapter1

参数列表格式:参数名=参数值&参数名=参数值....

例如: http://192.168.1.100:8080/helloworld/index.jsp?username=chai&password=123

 

URL url = new URL("http://www.baidu.com:80/index.html?keyword=java");
        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.getRef());//注意如果存在锚点,那么查询名返回null,因为#后面全部当做锚点了
        System.out.println("获取该url的查询名字:" + url.getQuery());
        public final InputStream openStream():返回一个用于从该连接读入的 InputStream。

 

URL url2 = new URL("http://www.baidu.com");
        InputStream input = url.openStream(); //返回一个用于从该连接读入的 InputStream
        byte[] data = new byte[1024];
        int len;
        while((len = input.read(data)) != -1){
            String s = new String(data, 0, len, "UTF-8");
            System.out.println(s);
        }
        
        input.close();

URLConnection

URL的方法openStream(),能从网络上读取数据,但是无法给服务器端发送数据,若希望给服务器端发送数据,则需要URLConnection。

它代表应用程序和 URL 之间的通信链接。此类的实例可用于读取和写入此 URL 引用的资源。通常,创建一个到 URL 的连接需要几个步骤:

  1. 通过 URL对象调用 openConnection 方法创建URLConnection连接对象。
  2. 处理设置参数和一般请求属性。
  3. 使用 connect 方法建立到远程对象的实际连接。

远程对象变为可用。远程对象的头字段和内容变为可访问

 

 从客户端读取发生给服务端(服务端做处理再返回给客户端)

public class TestServer {

    public static void main(String[] args) throws IOException {
        
        //1.开启服务,等待客户端连接
        ServerSocket server = new ServerSocket(9999);//开启服务器
        Socket socket = server.accept(); //接收客户的连接
        System.out.println("开启服务,连接成功");
        //2.接收客户端发来的消息输入:
        InputStream inputStream = socket.getInputStream(); //以字节流接收客户端的信息,通过socket接收
        InputStreamReader isr = new InputStreamReader(inputStream); //把字节流转成字符流
        BufferedReader br = new BufferedReader(isr);//提高效率加上缓冲流
        //3.给客户端返回消息输出:
        OutputStream os = socket.getOutputStream(); //输出,通过socket输出
        PrintStream ps = new PrintStream(os);
        //System.out.println(ps);
        //对接收的消息做处理
        String line;
        while((line = br.readLine()) != null){
            StringBuilder s = new StringBuilder(line);
            System.out.println("收到消息:" + s.toString());
            s.reverse();
            ps.println(s); 
            System.out.println("已做处理:" + s);
        }
        ps.close();
        os.close();
        br.close();
        isr.close();
        inputStream.close();
        socket.close();
        server.close();
    
    }
}
public class Testclient {

    public static void main(String[] args) throws UnknownHostException, IOException {
        
        //1.连接服务器
        Socket socket = new Socket("localhost", 9999);
        //2.从键盘输入消息
        Scanner input = new Scanner(System.in); //输入流inputStream
        //3.输出给服务端
        OutputStream outputStream = socket.getOutputStream();//以字节流通过socket输出给服务端
        PrintStream ps = new PrintStream(outputStream);//按行打印
        //4.接收服务端发来的消息
        InputStream inputStream = socket.getInputStream(); //从网络中通过socket接收服务端发来的
        InputStreamReader isr = new InputStreamReader(inputStream);//把字节流转成字符流
        BufferedReader br = new BufferedReader(isr); //用缓存包装
        //对键盘输入的信息做处理
        while(true){
            System.out.println("单词:");
            String word = input.next(); //从键盘中接收消息
            if("bye".equals(word)){
                break;
            }
            System.out.println("从键盘输入:" + word);
            ps.println(word); //给服务器发送单词消息; ps.print(word)用这个发送不出去!!!!
            
            String line = br.readLine();
            System.out.print("返回的单词是:" + line);
        }
        inputStream.close();
        outputStream.close();
        input.close();
        socket.close();
        
    }
}

 接收多个客户端发来的消息

package com.atguigu.manytcpsendword;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

public class TestServer {

    public static void main(String[] args) throws IOException {
        //1. 开启服务器
        ServerSocket server = new ServerSocket(8080);
        //2. 接收n个客户端发来的消息
        while(true){
            Socket socket = server.accept();
            
            String ip = socket.getInetAddress().getHostAddress();
            System.out.println(ip + "接入");//记录接入的ip地址
            MyMessage m = new MyMessage(socket);  //在构造器中赋值
            m.start();
        }
        
    }
}

class MyMessage extends Thread{
    
    private Socket socket; //socket负责收发消息,
    
    public MyMessage(Socket socket) {
        super();
        this.socket = socket;
    }
    public void run(){
        
        InputStream is = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        OutputStream os = null;
        PrintStream ps = null;
        try {
            //1. 接收客户端发来的消息,从网络中读取-->字节流-字符流 -->
            is = socket.getInputStream();
            isr = new InputStreamReader(is);
            br = new BufferedReader(isr);
            
            //2. 对接收的消息做处理然后返回给客户端
            os = socket.getOutputStream();
            ps = new PrintStream(os);
            
            String line;
            
            while((line = br.readLine()) != null){
                
                //line = br.readLine();
                StringBuffer s = new StringBuffer(line);
                s.reverse();
                ps.println(s);
                System.out.println("已处理完毕并返回给客户端" + s);
            }
            
            
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        try {
            ps.close();
            os.close();
            br.close();
            isr.close();
            is.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //server.close();
    }
    
}
View Code
package com.atguigu.manytcpsendword;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;

public class TestClient {

    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("localhost", 8080);
        Scanner input = new Scanner(System.in);
        //输出给服务端
        OutputStream os = socket.getOutputStream();
        PrintStream ps = new PrintStream(os);
        
        //接收服务端消息
        InputStream is = socket.getInputStream();
        InputStreamReader isr = new InputStreamReader(is);//把接收的字节转成字节
        BufferedReader br = new BufferedReader(isr); //把字节包装下提高效率
        while(true){
            System.out.println("留言:");
            String str = input.next();
            
            if("bye".equalsIgnoreCase(str)){
                break;
            }
            //给服务端发 消息
            ps.println(str);
            //接收服务端发来的消息
            String line = br.readLine();
            System.out.println("接收到服务端发来的消息:" + line);
        }
        br.close();
        isr.close();
        is.close();
        ps.close();
        os.close();
        input.close();
        socket.close();
        
    }
        
}
View Code

传输文件

public class Server {

    public static void main(String[] args) throws IOException {
        //1.创建服务器
        ServerSocket server = new ServerSocket(9999);
        
        Socket socket = server.accept();
        
        String ip = socket.getInetAddress().getHostAddress();
        System.out.println(ip + "已接入");
        //2.从客户端读取数据
        DataInputStream dis = new DataInputStream(socket.getInputStream());
        String fileName = dis.readUTF();
        
        
            //先确定输出文件的路径,然后再写入数据
        FileOutputStream fos = new FileOutputStream("upload/" + fileName);
            //读取内容
        byte[] data = new byte[1024];
        int len;
        while((len = dis.read(data)) != -1){
            fos.write(data, 0, len);
        }
        //3.写完之后给客户端回个信号
        PrintStream ps = new PrintStream(socket.getOutputStream());
        ps.println("接收完毕,请客户端查阅");
        
        ps.close();
        fos.close();
        dis.close();
        socket.close();
        server.close();
        
    }
    
    
}
public class Client {

    public static void main(String[] args) throws UnknownHostException, IOException {
        
        //1.连接服务器
        Socket socket = new Socket("localhost", 9999);
        
        //2.给服务器上传文件
            //一.先输入地址
        Scanner input = new Scanner(System.in);
        
        System.out.println("文件地址:");
        String filePath = input.next();
        File file = new File(filePath); //因为它是一个file字符串路径对象,所以要用DataIn。。
        String pathName = file.getName();
        
            //二.把文件路径和文件名对象化传给服务端
        DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
        dos.writeUTF(pathName); //对象化文件名后,读取时还要同样的readUTF( )
        
            //三.按照字节读取文件内容
        FileInputStream fis = new FileInputStream(file);
        
        
        byte[] data = new byte[1024];
        int len;
        while((len = fis.read(data)) != -1){ //读取文件内容并写入
            dos.write(data, 0, len);
            
        }
        socket.shutdownOutput(); //要先关闭输出流
        
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); //接收服务端返回的字符串
        String line = br.readLine();
        System.out.println("接收服务端返回的结果:" + line);
        br.close();
        fis.close();
        dos.close();
        input.close();
        socket.close();
        
    }
}

可接收多个客户端发来的文件

package com.atguigu.fileputmany;

import java.io.DataInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

    public static void main(String[] args) throws IOException {
        //1.创建服务器
        ServerSocket server = new ServerSocket(9999);

        while(true){
            Socket socket = server.accept();
            String ip = socket.getInetAddress().getHostAddress();
            System.out.println(ip + "已接入");
            MyFile m = new MyFile(socket);
            m.start();

        }
    }
}

class MyFile extends Thread{
    private Socket socket;

    public MyFile(Socket socket) {
        super();
        this.socket = socket;
    }
    
    public void run(){
        //2.从客户端读取数据
        DataInputStream dis = null;
        FileOutputStream fos = null;
        PrintStream ps = null;
        try {
            dis = new DataInputStream(socket.getInputStream());
            String fileName = dis.readUTF();
            //先确定输出文件的路径,然后再写入数据
        fos = new FileOutputStream("upload/" + fileName);
            //读取内容
        byte[] data = new byte[1024];
        int len;
        while((len = dis.read(data)) != -1){
            fos.write(data, 0, len);
        }
        //3.写完之后给客户端回个信号
        ps = new PrintStream(socket.getOutputStream());
        ps.println("接收完毕,请客户端查阅");
                    
        } catch (IOException e1) {
            e1.printStackTrace();
        }

        try {
            ps.close();
            fos.close();
            dis.close();
            socket.close();
            //server.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        

        
    }
    
}
View Code
package com.atguigu.fileputmany;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class Client {

    public static void main(String[] args) throws UnknownHostException, IOException {
        
        //1.连接服务器
        Socket socket = new Socket("localhost", 9999);
        
        //2.给服务器上传文件
            //一.先输入地址
        Scanner input = new Scanner(System.in);
        
        System.out.println("文件地址:");
        String filePath = input.next();
        File file = new File(filePath); //因为它是一个file字符串路径对象,所以要用DataIn。。
        String pathName = file.getName();
        
            //二.把文件路径和文件名对象化传给服务端
        DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
        dos.writeUTF(pathName); //对象化文件名后,读取时还要同样的readUTF( )
        
            //三.按照字节读取文件内容
        FileInputStream fis = new FileInputStream(file);

        byte[] data = new byte[1024];
        int len;
        while((len = fis.read(data)) != -1){ //读取文件内容并写入
            dos.write(data, 0, len);
            
        }
        socket.shutdownOutput(); //要先关闭输出流,不然接收不到服务端返回的消息

        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); //接收服务端返回的字符串
        String line = br.readLine();
        System.out.println("接收服务端返回的结果:" + line);
        br.close();
        fis.close();
        dos.close();
        input.close();
        socket.close();
    }
}
View Code

用TCP实现多人聊天

package com.atguigu.chat;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class TestServer {

    public static void main(String[] args) throws IOException {
        //1.启动服务器
        ServerSocket server = new ServerSocket(9999);
        ArrayList<Socket> onLine = new ArrayList<Socket>(); //创建集合装开启的线程;
        
        while(true){
            Socket socket = server.accept();
            System.out.println(socket.getInetAddress().getHostAddress() + "连接成功");
            //每连接一个,往里边放一个
            onLine.add(socket);
            Message m = new Message(socket, onLine);
            m.start();
        }
    
    }
}

class Message extends Thread{
    private Socket socket;
    private ArrayList<Socket> onLine;
    private String ip;
    public Message(Socket socket, ArrayList<Socket> onLine) {
        super();
        this.socket = socket;
        this.onLine = onLine;
    }
    public void run(){
        ip = socket.getInetAddress().getHostAddress();
        sendToOther(ip + "上线了"); //小功能,xx上线了,在receive公共聊天室;
        
        BufferedReader br = null;
        try {
            //接收客户端的消息; 把字节变成字符流并提高效率
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String line;
            while((line = br.readLine()) != null){
                //把消息转发给其他的客户端receive公共聊天室;这里写一个方法
                sendToOther(line);    
            }    
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                br.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            onLine.remove(socket);
            sendToOther(ip + "下线了");
        }
    }
    public void sendToOther(String str){
        
        ArrayList<Socket> offline = new ArrayList<Socket>();
        
        for (Socket socket :onLine) { //遍历的是onLine!!!!
            if(!(socket.equals(this.socket))){ //如果不是自己就转发
                try{
                    PrintStream ps = new PrintStream(socket.getOutputStream());
                    ps.println(str);
                }catch(IOException e){
                    e.printStackTrace();
                    offline.add(socket);
                }
            }
        }
        for (Socket off : offline) {
            offline.remove(off);
        }
    }
}
View Code
package com.atguigu.chat;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class TestClient {

    public static void main(String[] args) throws UnknownHostException, IOException {
        //1.连接服务器
        Socket socket = new Socket("localhost",9999);
        //创建两个线程,一个用来发send消息; 一个用来接收receive消息(作为公共的聊天场所)
        Send send = new Send(socket);
        Receive receive = new Receive(socket);
        
        send.start();
        receive.start();
        
        try {
            send.join();
            receive.setExited(true);
            receive.join();
        } catch (InterruptedException e) {
        
            e.printStackTrace();
        }
        socket.close();
        
    }
}

class Send extends Thread{
    
    private Socket socket;

    public Send(Socket socket) {
        super();
        this.socket = socket;
    }
    
    public void run(){
        Scanner input = new Scanner(System.in); //从键盘输入消息
        
        PrintStream ps = null;
        try {
            ps = new PrintStream(socket.getOutputStream());//将键盘输入的消息发出
            while(true){
                System.out.println("畅聊:");
                String message = input.nextLine();
                if("bye".equalsIgnoreCase(message)){
                    break;
                }
                ps.println(message); //发送出去;
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            input.close();
        }
        
    }
    
}

class Receive extends Thread{
    
    private Socket socket;
    private boolean exited;

    public Receive(Socket socket) {
        super();
        this.socket = socket;
    }
    public void setExited(boolean exited) {
        this.exited = exited;
    }
    
    public void run(){
        BufferedReader br = null;
        try {
            //字节输入流 -->字符 --> 包装下提高效率
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String line;
            while((line = br.readLine()) != null && !exited){
                System.out.println(line);
            }
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
View Code

 基于UDP多人聊天(使用MulticastSocket实现多点广播)

package com.atguigu.udp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.Scanner;

public class TestMulticastSocket {
    static Scanner input = new Scanner(System.in);
    static String username;
    
    public static void main(String[] args) throws IOException {
        //1. 创建Socket
        MulticastSocket ms = new MulticastSocket(9999); 
        InetAddress ip = InetAddress.getByName("230.0.0.1");
    
        ms.joinGroup(ip); //把这个ms添加到广播组中
        ms.setLoopbackMode(false); //如果为true是禁止回传;
        
        System.out.println("用户名:");
        username = input.nextLine();
        
        Send send = new Send(ms, ip);
        Receive receive = new Receive(ms);
        
        send.start();
        receive.start();
        
        try {
            send.join();
            receive.setExited(true);
            receive.join();
            
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        ms.close();
        
    }
    
    static class Send extends Thread{ //静态内部类
        private MulticastSocket socket; //
        private InetAddress ip; //
        public Send(MulticastSocket socket, InetAddress ip) {
            super();
            this.socket = socket;
            this.ip = ip;
        }
        public void run(){
            while(true){
                System.out.println("输入消息:");
                String message = input.nextLine();
                if("bye".equalsIgnoreCase(message)){
                    break;
                }
                //1.创建数据报DatagramPacket
                byte[] data = (username + "说:" + message).getBytes(); //把键盘输入的转成字节数组
                DatagramPacket dp = new DatagramPacket(data, data.length, ip, 9999);
                
                try {
                    //2.调用调用MulticastSocket类socket 的send方法将数据报发送出去;
                    socket.send(dp);
                    
                } catch (IOException e) {
                    e.printStackTrace();
                }
                
            }
            
        }
        
    }
    static class Receive extends Thread{
        private MulticastSocket socket;
        private boolean exited;
        public Receive(MulticastSocket socket) {
            super();
            this.socket = socket;
        }
        public void setExited(boolean exited) {
            this.exited = exited;
        }

        public void run(){
            
            while(!exited){
                //1.建立数据报DatagramPacket
                byte[] data = new byte[1024];
                DatagramPacket dp = new DatagramPacket(data, data.length);
                try {
                    //2.调用MulticastSocket socket的seceive方法发送数据报;
                    socket.receive(dp);
                    //3.拆解数据报
                    int len = dp.getLength();
                    System.out.println("本次收到的消息:" + new String(data, 0, len));
                    
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        
    }
    
}
View Code

基于UDP协议的网络编程

   TCP:(Transmission Control Protocol,传输控制协议),面向连接的,可靠的,基于字节流的传输层的网络协议。
   服务器端:ServerSocket和Socket,客户端:Socket
  getInputStream()和getOutputStream()
   UDP:(User Datagram Protocol,用户数据报协议),非面向连接的(无连接的),面向事务的基于数据报的不可靠的传输层的网络协议。

   UDP:快,适用于(是否接收到消息要求不高,但是对速度要求高,必须小的),大小限制在64K

   通信的两端也有Socket:DatagramSocket
   DatagramPacket数据报

1、“发送端”
步骤流程:
1、建立发送端的DatagramSocket,需要指定本端的端口号
2、建立数据包DatagramPacket
    数据
    接收端的IP地址
    接收端的端口号
3、调用DatagramSocket的发送方法
4、关闭DatagramSocket

2、“接收端”
步骤流程:
1、建立接收端的DatagramSocket,需要指定本端的IP地址和端口号
2、建立数据包DatagramPacket
    需要指定装数据的数组
3、调用Socket的接收方法
4、拆封数据
5、关闭Socket

 

posted @ 2018-12-16 14:25  kris12  阅读(207)  评论(0编辑  收藏  举报
levels of contents