Java 网络编程入门

前言

了解Java网络编程,打好网络编程的基础。

一、TCP消息发送

1、Client

package com.xhu.java.net;

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

public class TCPClient {
    public static void main(String[] args) {
        //获取本机IP地址
        InetAddress clientServer = null;
        Socket socket = null;
        OutputStream outputStream = null;
        try {
            clientServer = InetAddress.getByName("127.0.0.1");
            //设置一个端口号
            int port = 9999;
            //生成socket
            socket = new Socket(clientServer, port);
            //发送消息
            outputStream = socket.getOutputStream();
            outputStream.write("学TCP".getBytes());
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭流
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            //关闭socket
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }
}

2、Server

package com.xhu.java.net;

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

public class TCPServer {
    public static void main(String[] args) {
        //服务端IP+端口,即socket
        ServerSocket serverSocket = null;
        Socket accept = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;
        try {
        //开放端口
            serverSocket = new ServerSocket(9999);
            //接收客户端的连接
            accept = serverSocket.accept();
            //把信息读出来
            is = accept.getInputStream();
            //为了防止乱码,用字节数组包装流读出正确的字符
            baos = new ByteArrayOutputStream();
            int n = 0;
            while (true) {
                try {
                    if (!((n = is.read()) != -1)) break;
                } catch (IOException e) {
                    e.printStackTrace();
                }
                baos.write(n);

            }
            System.out.println(baos.toString());
        } 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 (accept != null) {
                try {
                    accept.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (serverSocket != null) {
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

二、UDP消息发送

UDP不建立连接,发完包就不管了。

package com.xhu.java.net;

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

public class UDPClient {
    public static void main(String[] args) throws IOException {
        //1.创建socket
        DatagramSocket socket = new DatagramSocket();
        //2.发送包
        socket.send(new DatagramPacket("udp信息可有可无".getBytes(),
                0, "udp信息可有可无".getBytes().length, InetAddress.getByName("localhost"), 9999));
        //3.关闭
        socket.close();
        //就这样给服务端发送了,不用建立连接,发了就不管了。
    }
}

package com.xhu.java.net;

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

public class UDPServer {
    public static void main(String[] args) throws IOException {
        //1.开放端口
        DatagramSocket socket = new DatagramSocket(9999);
        //2.接收包
        byte[] buffer = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
        //阻塞接收
        socket.receive(packet);
        //输出数据
        System.out.println(new String(packet.getData(), 0, packet.getLength()));
        System.out.println(packet.getAddress());
        //关闭连接
        socket.close();
        //这是不严格的服务端,不建立连接,只有发送端和接收端。这里也可以给其它发。
    }
}

三、UDP聊天

1、发送方

package com.xhu.java.net;

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

public class UDPClientA {
    public static void main(String[] args) throws IOException {
        //1.创建socket,开放一个端口
        DatagramSocket socket = new DatagramSocket(9998);
        //2.发送包
        //获取键盘输入
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        while (true) {
            String msg = br.readLine();
            byte[] msgBytes = msg.getBytes();
            InetAddress receive = InetAddress.getByName("localhost");
            int port = 9999;
            DatagramPacket packet = new DatagramPacket(msgBytes, 0, msgBytes.length, receive, port);
            socket.send(packet);
            if ("bye".equalsIgnoreCase(msg)) {
                //关闭连接
                br.close();
                socket.close();
                break;
            }
        }
        //就这样给服务端发送了,不用建立连接,发了就不管了。
    }
}

2、接收方

package com.xhu.java.net;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class UDPClientB {
    public static void main(String[] args) throws IOException {
        //1.开放端口
        DatagramSocket socket = new DatagramSocket(9999);
        //2.接收包
        while (true) {
            byte[] buffer = new byte[1024];
            DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
            //阻塞接收
            socket.receive(packet);
            //输出数据
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
            String msg = new String(packet.getData(), 0, packet.getLength());
            bw.write(packet.getAddress() + ":" + msg);
            bw.flush();
            bw.newLine();
            if ("bye".equalsIgnoreCase(msg)) {
                //关闭连接
                bw.close();
                socket.close();
                break;
            }
        }
        //这是不严格的服务端,不建立连接,只有发送端和接收端。这里也可以给其它发。
    }
}

四、多线程UDP聊天

先了解多线程入门

1、ClientA

package com.xhu.java.net;

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

public class UDPClientA {
    public static void main(String[] args) throws IOException {
        //1.开放端口
        DatagramSocket socket = new DatagramSocket(9998);
        Send s = new Send(socket);
        Receive r = new Receive(socket);
        new Thread(s).start();
        new Thread(r).start();
    }

    //发送线程
    static class Send implements Runnable {
        private DatagramSocket socket;

        public Send(DatagramSocket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            //2.发送包
            //获取键盘输入
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            while (true) {
                String msg = null;
                try {
                    msg = br.readLine();
                    byte[] msgBytes = msg.getBytes();
                    InetAddress receive = InetAddress.getByName("localhost");
                    int port = 9999;
                    DatagramPacket packet = new DatagramPacket(msgBytes, 0, msgBytes.length, receive, port);
                    socket.send(packet);
                    if ("bye".equalsIgnoreCase(msg)) {
                        //关闭连接
                        br.close();
                        socket.close();
                        break;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //接收线程
    static class Receive implements Runnable {
        private DatagramSocket socket;

        public Receive(DatagramSocket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            //2.接收包
            while (true) {
                byte[] buffer = new byte[1024];
                DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
                //阻塞接收
                try {
                    socket.receive(packet);
                    //输出数据
                    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
                    String msg = new String(packet.getData(), 0, packet.getLength());
                    bw.write(packet.getAddress().getHostName() + ":" + String.valueOf(packet.getPort()) + ":" + msg);
                    bw.flush();
                    bw.newLine();
                    bw.flush();
                    if ("bye".equalsIgnoreCase(msg)) {
                        //关闭连接
                        bw.close();
                        socket.close();
                        break;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }
}

2、ClientB

package com.xhu.java.net;

import java.io.*;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UDPClientB {
    public static void main(String[] args) throws IOException {
        //1.开放端口
        DatagramSocket socket = new DatagramSocket(9999);
        Send s = new Send(socket);
        Receive r = new Receive(socket);
        new Thread(s).start();
        new Thread(r).start();
    }

    //发送线程
    static class Send implements Runnable {
        private DatagramSocket socket;

        public Send(DatagramSocket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            //2.发送包
            //获取键盘输入
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            while (true) {
                String msg = null;
                try {
                    msg = br.readLine();
                    byte[] msgBytes = msg.getBytes();
                    InetAddress receive = InetAddress.getByName("localhost");
                    int port = 9998;
                    DatagramPacket packet = new DatagramPacket(msgBytes, 0, msgBytes.length, receive, port);
                    socket.send(packet);
                    if ("bye".equalsIgnoreCase(msg)) {
                        //关闭连接
                        br.close();
                        socket.close();
                        break;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //接收线程
    static class Receive implements Runnable {
        private DatagramSocket socket;

        public Receive(DatagramSocket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            //2.接收包
            while (true) {
                byte[] buffer = new byte[1024];
                DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
                //阻塞接收
                try {
                    socket.receive(packet);
                    //输出数据
                    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
                    String msg = new String(packet.getData(), 0, packet.getLength());
                    bw.write(packet.getAddress().getHostName() + ":" + String.valueOf(packet.getPort()) + ":" + msg);
                    bw.flush();
                    bw.newLine();
                    bw.flush();
                    if ("bye".equalsIgnoreCase(msg)) {
                        //关闭连接
                        bw.close();
                        socket.close();
                        break;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }
}

注:
1)这里有些bug啊,比如结束时,一个线程over,应该关联另一个线程,也让它over。这里主要体现思想,能通信,仅供参考。
2)如发送、接收线程体只用写原始的两个类,可以传入socket和port来完成不同的socket的线程。

五、URL下载网络资源

package com.xhu.java.net;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;

public class DownByURL {
    public static void main(String[] args) {
        //下载地址(下载字符)
        String urlName = "https://img-baofun.zhhainiao.com/market/133/2366564fa6b83158208eb3181752a8d6_preview.mp4";//协议:/域名或IP:端口/项目/资源
        InputStream is = null;
        OutputStream osw = null;
        try {
            URL url = new URL(urlName);
            //连接
            HttpURLConnection uc = (HttpURLConnection) url.openConnection();
            is = new BufferedInputStream(uc.getInputStream());
            osw = new BufferedOutputStream(new FileOutputStream("壁纸.mp4"));
            int n = 0;
            while ((n = is.read()) != -1) {
                osw.write(n);
            }
            osw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (osw != null) {
                try {
                    osw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

总结

通信靠 socket,网络通信就是socket里的InputStream / OutputStream

参考文献

[1] Java 网络编程 狂神

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值