TCP和UDP用Java实现

查询进程

netstat -ano #查看所有的端口
netstat -ano|findstr "5900" # 查看指定端口
tasklist|findstr "8696 #查看指定端口进程

TCP和UDP的区别

TCP相当于打电话

  • 连接稳定
  • 三次握手、四次挥手

三次握手:
A:你瞅啥?
B:瞅你咋滴?
A:干一场(连接建立成功,信息开始传输)

四次挥手:

A:我要走了!
B:你真的要走了吗?
B:你真的真的要走了吗?
A:我真的要走了!

  • 客户端、服务端分开
  • 传输完成,释放连接、效率低

UDP

  • 相当于发短信
  • 不进行连接,不稳定
  • 客户端、服务端没有明确的界线
  • 不管是否准备好,都可以进行连接

TCP通信实战

这里分为客户端和服务端
客户端:

  1. 连接服务端Socket
  2. 发送消息
//TCP客户端
public class TCPClientDemo01 {
    public static void main(String[] args) {
        OutputStream os = null;
        Socket socket = null;
        //连接服务器
        try {
            //1.要知道服务端的地址,端口号
            InetAddress serverIP = InetAddress.getByName("127.0.0.1");
            int port = 9999;

            //2.创建一个socket连接
            socket = new Socket(serverIP, port);

            //3.发送消息IO流
            os = socket.getOutputStream();
            os.write("您好Java".getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //注意关闭流的顺序和打开流的顺序要相反
            //判断null避免空指针异常
            if(os != null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

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

服务端:

  1. 建立服务的端口 ServerSocket
  2. 等待用户的连接 accept
  3. 接收用的消息
//TCP服务端
public class TcpServerDemo01 {
    public static void main(String[] args) {
        ServerSocket serverSocket = null;;
        Socket socket = null;
        InputStream is = null;;
        ByteArrayOutputStream baos = null;
        try {
            //1.得现有一个服务端地址
            serverSocket = new ServerSocket(9999);
            //这里一直循环可以一直接收客户端的请求
          while(true){
              //2.等待客户端进行连接
              socket = serverSocket.accept();
              //3.读取客户端的消息
              is = socket.getInputStream();

              //管道流来处理消息
              baos = new ByteArrayOutputStream();
              byte[] buffer = new byte[1024];
              int len;
              while((len=is.read(buffer))!=-1){
                  baos.write(buffer,0,len);
              }
              System.out.println(baos);
          }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(baos != null){
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if(is != null){
                try {
                    is.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();
                }
            }


        }
    }
}

文件上传

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

        //3.读取文件
        FileInputStream fis = new FileInputStream(new File("upLoadImager.png"));

        //4.写出文件
        byte[] buffer = new byte[1024];
        int len;
        while ((len=fis.read(buffer))!=-1){
            os.write(buffer,0,len);
        }


        //通知服务器,我已经上传结束了
        socket.shutdownOutput();    //我已经传输完成

        //确定服务端接收完毕,断开连接
        InputStream inputStream = socket.getInputStream();

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer2 = new byte[1024];
        int len2;
        while((len2=inputStream.read(buffer2))!=-1){
            baos.write(buffer2,0,len2);
        }

        System.out.println(baos);
        
        //5.关闭资源
        baos.close();
        inputStream.close();
        fis.close();
        os.close();
        socket.close();
    }
}
public class TcpServerDemo02 {
    public static void main(String[] args) throws IOException {
        //1.创建服务
        ServerSocket serverSocket = new ServerSocket(9000);
        //2.监听客户端连接
        Socket socket = serverSocket.accept();
        //3.获取输入流
        InputStream is = socket.getInputStream();

        //4.文件输出
        FileOutputStream fos = new FileOutputStream(new File("receive.png"));
        byte[] buffer = new byte[1024];
        int len;
        while((len=is.read(buffer))!=-1){
            fos.write(buffer,0,len);
        }

        //通知客户端服务端接收完毕了——对应TCP的握手与挥手
        OutputStream os = socket.getOutputStream();
        os.write("接收完毕,可以断开".getBytes());

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

UDP进行通信

发送端

public class UdpSendDemo01 {
    public static void main(String[] args) throws IOException {
        //1.建立Socket连接
        DatagramSocket socket = new DatagramSocket();
        //2.建个包
        String msg = "您好Java";
        InetAddress localhost = InetAddress.getByName("localhost");
        int port = 9090;

        //数据,数据长度起始,发给谁
        DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port);

        //3.发送包
        socket.send(packet);
        //4.关闭流
        socket.close();
    }
}

接收端

public class UdpReceiveDemo01 {
    public static void main(String[] args) throws IOException {
        //开放端口
        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();
    }
}

UDP实现聊天框

因为聊天框需要同时一起进行发送消息,所以在这里使用多线程进行实现。
消息类都实现了Runnable类。

发送类

public class TalkSend implements Runnable{
    DatagramSocket socket = null;
    BufferedReader reader = null;

    private int fromPort;
    private String toIP;
    private int toPort;

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

    @Override
    public void run() {

        while(true){
            String data = null;
            try {
                data = reader.readLine();

                byte[] datas = data.getBytes();
                DatagramPacket pakcet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress(this.toIP, this.toPort));

                socket.send(pakcet);
                if(data.equals("bye")){
                    break;
                }
            }catch (IOException e) {
                e.printStackTrace();
            }
        }
        socket.close();
    }
}

接收类

public class TalkReceive implements Runnable{

    DatagramSocket socket = null;
    private int port;
    private String receiver;

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

    }

    @Override
    public void run() {
        while(true){

            //接受包
            byte[] container = new byte[1024];
            DatagramPacket packet = new DatagramPacket(container, 0, container.length);

            try {
                socket.receive(packet);


                //断开连接  bye
                byte[] data = packet.getData();
                String receiveData = new String(data, 0, data.length);
                System.out.println(receiver+receiveData);

                //发送bye时,跳出循环,即断开连接
                if(receiveData.equals("bye")){
                    break;
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        socket.close();
    }
}

学生类

public class TalkStu {
    public static void main(String[] args) {
        new Thread(new TalkSend(7777,"localhost",9999)).start();
        new Thread(new TalkReceive(8888,"老师")).start();
    }
}

老师类

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

使用URL下载资源

只要知道某一个资源的所在位置(URL,统一资源定位符)
那么就可以给它下载下来。

public class URLTest {

    public static void main(String[] args) throws IOException {
        //1.下载地址(该地址是从网上随便找的一个图片的所在路径)
        URL url = new URL("https://i1.hdslb.com/bfs/face/e3637ff7fa559e53a6bd4a8521b9446619f00cad.jpg@160w_160h_1c_1s.webp");
        //下载什么格式的文件,则文件后缀名需要对应上
        String fileName = "46619f00cad.jpg";

        //2.连接到该资源 HTTP
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

        InputStream inputStream = urlConnection.getInputStream();
        FileOutputStream fos = new FileOutputStream(fileName);

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

        //关闭资源
        fos.close();
        inputStream.close();
        urlConnection.disconnect();
    }
}

你可能感兴趣的:(Java笔记,网络编程,udp,tcp/ip,java)