Java网络通信(TCP+UDP+URL)

前言

  • 网络通信需要协议,我们了解一下今天的主角:

TCP(传输控制协议):通信双发需要建立连接,安全、可靠。有严格意义上的客户端、服务端
例如:打电话

UDP(用户数据包协议):不需要建立连接,不可靠。任何一个方都可以成为客户端、服务端
例如:发短信

  • 网络通信还需要知道对方的端口号IP
    InetAddress封装了一系列static方法,可以获取主机信息.
    在这里插入图片描述

    此外,还有InetSocketAddress ,该类实现IP套接字地址(IP地址+端口号)
    在这里插入图片描述

    TCP

    • 客户端
import java.io.IOException;

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


//客户端
public class TcpClientDemo {
    static Socket socket = null;
    static   OutputStream on = null;
    public static void main(String[] args) {
        try {
//            需要知道服务器端地址、端口号
            InetAddress inetAddress =  InetAddress.getByName("127.0.0.1");
            int port = 5900;
//            创建一个socket连接
            socket = new Socket(inetAddress,port);
//			获取输出流
            on =  socket.getOutputStream();

            on.write("你好,欢迎使用TCP连接".getBytes());

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(on!=null){
                try {
                    on.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(socket!=null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

}

  • 服务端
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

//服务端
public class TcpServerDemo {
    static ServerSocket server = null;
    static Socket socket = null;
    static InputStream in = null;
    static ByteArrayOutputStream out = null;

    public static void main(String[] args) {
        try {
//            服务器需要一个地址
            server = new ServerSocket(5900);

            // 等待客户端连接(阻塞等待)
            socket = server.accept();
//           读取客户端信息
            in = socket.getInputStream();

//          管道字节流
            out = new ByteArrayOutputStream();
            byte[] buff = new byte[1024];
            int len;
            while ((len = in.read(buff)) != -1) {
                out.write(buff, 0, len);
            }
            System.out.println(out.toString());

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (server != null) {
                try {
                    server.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

注意:这里建议养成好的习惯,关闭资源,要写代码注释

实现文件上传

客户端上传文件给服务器端,服务器端收到文件后通知客户端并断开连接

  • 服务端
import java.io.File;
import java.io.FileOutputStream;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

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

        ServerSocket server = new ServerSocket(7800);
//        监听客户端的连接(阻塞式)
        Socket socket = server.accept();

        InputStream inputStream = socket.getInputStream();

        FileOutputStream fileOutputStream = new FileOutputStream(new File("recever.png"));

        byte[] buff = new byte[1024];
        int len;
        while ((len = inputStream.read(buff))!=-1){
            fileOutputStream.write(buff,0,len);
        }

//        通知客户端我接收完毕
        OutputStream os = socket.getOutputStream();
        os.write("文件已接收,你可以断开连接了!".getBytes());

        os.close();
        fileOutputStream.close();
        inputStream.close();
        socket.close();
        server.close();

    }
}

  • 客户端
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;


public class TcpClientDemo {
    public static void main(String[] args) throws Exception {
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),7800);

        OutputStream out =  socket.getOutputStream();

//        读取文件
        FileInputStream fileInputStream = new FileInputStream(new File("timg.jpeg"));

//        写入文件
        byte[] buff = new byte[1024];
        int len;
        while((len=fileInputStream.read(buff))!=-1){
                out.write(buff,0,len);
        }


//    通知服务器,文件传输完毕,断开连接
        socket.shutdownOutput();

//        确定服务器已收到,断开连接
        InputStream is = socket.getInputStream();

//        通过管道流接收服务端信息
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] b = new byte[1024];
        int le;
        while((le=is.read(b))!=-1){
            baos.write(b,0,le);
        }
        System.out.println(baos.toString());

        baos.close();
        is.close();
        fileInputStream.close();
        out.close();
        socket.close();
    }
}

ByteArrayOutputStream 字节数组输出流,这里用到是相当一个管道,避免出现中文乱码现象。

UDP

  • DatagramSocket :是用于发送和接收数据。
  • DatagramPacket :打包数据

DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port)
构造用于发送长度的分组数据报包 length具有偏移 ioffset指定主机上到指定的端口号。

import java.net.*;

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

        DatagramSocket socket = new DatagramSocket(5050,InetAddress.getByName("localhost"));

        String msg ="UDP无连接发信息";
        DatagramPacket packet = new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,InetAddress.getByName("localhost"),4040);

        socket.send(packet);

        socket.close();
    }
}

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


public class Udp2Demo {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(5050);

        byte[] bytes = new byte[1025];
        DatagramPacket packet = new DatagramPacket(bytes,0,bytes.length);

        socket.receive(packet);

        System.out.println(packet.getData());
        socket.close();
    }
}

多线程聊天

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

public class TalkReceive implements Runnable {

    DatagramSocket socket =null;
    private int fromPort;
    private String msgFrom;

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

    @Override
    public void run() {


        while (true){
            try {
                byte[] b = new byte[1024];
                DatagramPacket packet = new DatagramPacket(b,0,b.length);
                socket.receive(packet);
                String str = new String(packet.getData(),0,packet.getLength());
                System.out.print(msgFrom+" : "+str);
                if(str.equals("bye")){
                    break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        socket.close();
    }
}

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

public class TalkSender implements Runnable {
    DatagramSocket socket =null;
    BufferedReader scan =null;

    private int fromPort;
    private String toIp;
    private int toPort;

    public TalkSender(int fromPort, String toIp, int toPort) {
        this.fromPort = fromPort;
        this.toIp = toIp;
        this.toPort = toPort;
        try {
            socket = new DatagramSocket(fromPort, InetAddress.getByName(toIp));

            scan = new BufferedReader(new InputStreamReader(System.in));
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        while (true) {
            try {
                String msg = scan.readLine();

                DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, InetAddress.getByName(toIp), toPort);
                socket.send(packet);
                if (msg.equals("bye"))
                    break;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        socket.close();

    }

}

public class TalkStudent {
    public static void main(String[] args) {
        new Thread(new TalkSender(5555,"localhost",9999)).start();

        new Thread(new TalkReceive(7777,"老师")).start();
    }
}

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

到此,就可以聊天了。UDP相比较TCP更加简单,他不需要建立连接。

URL(统一资源定位符)

  • 顾名思义,是用来定位资源的嘛~
  • 组成: 协议://IP地址:端口号/项目名
    例如:https://www.baidu.com/baidu,这里隐藏了端口号

下载资源

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

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

        URL url = new URL("https://m10.music.126.net/20200822185011/f80542d39dd545f8c5238742801049ab/yyaac/obj/wonDkMOGw6XDiTHCmMOi/2180584755/addb/4c39/1202/a7e369ca61357fc66eab2467a823d356.m4a");

        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        InputStream in =  connection.getInputStream();

        FileOutputStream out = new FileOutputStream(new File("夏天的风.m4a"));

        byte[] buff = new byte[1024];
        int len;
        while ((len=in.read(buff))!=-1){
            out.write(buff,0,len);
        }
        out.close();
        in.close();
        connection.disconnect();

    }
}

下载成功莫名的激动,以后下资源。。嘿嘿。

希望这里对大家有所帮助,谢谢~~
依然有困惑的,可以搜索 blibli up主 遇见狂神说,看看它讲的这一节,非常的nice

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值