网络编程多线程优化

本文详细介绍了网络通信的基础知识,包括IP地址(IPv4和IPv6)、端口号的使用以及网络协议如TCP和UDP的特性。通过实例展示了InetAddress类的用法,以及UDP和TCP通信的过程。同时提到了单播、组播和广播三种通信方式在不同场景的应用。
摘要由CSDN通过智能技术生成

网络三要素

IP地址, 端口号, 网络协议

ip地址

表示网络中设备的唯一标识
ipv4: 由4个字节组成,采用点分十进制表示法
举例:192.168.66.202
ipv6: 由16个字节组成,采用冒分十六进制表示法
举例:fb34:66:77:ac:3f
常用的命令:
ipconfig: 查看本机的ip地址
ping: 检测网络和指定的ip是否连通

端口号

表示某一台主机上应用程序的表示,是一个[0,65535]范围内的整数.
0~1023的端口号可能会被占用,建议使用1024之后的端口号。

网络协议

网络中数据传输的规则
UDP: 面向无连接的,不安全的协议,每次传输64KB的数据
TCP: 面向有连接,安全的协议,传输数据的大小没有限制。

InetAddress类

public static InetAddress getByName(String host) 
    在给定主机名的情况下确定主机的 IP 地址。
public String	getHostAddress() 
	返回 IP 地址字符串(以文本表现形式)举例:"192.168.83.44"
public String	getHostName() 
    获取此 IP 地址的主机名。

举例

public class InetAddress0 {
    public static void main(String[] args) throws UnknownHostException {
        //确认IP地址或主机名称
        InetAddress byName = InetAddress.getByName("192.168.83.133");

        //获取IP地址
        String hostAddress = byName.getHostAddress();
        System.out.println("IP地址:"+hostAddress);

        //获取主机名称
        String hostName = byName.getHostName();
        System.out.println("主机名:"+hostName);



    }
}

UDP通信

UDP发送端

UDP: 面向无连接的,不安全的协议,每次传输64KB的数据

1.创建DatagramSocket对象(码头)
2.创建DatagramPacket对象(包裹) 需要制定ip地址和端口号
3.调用send方法,发送数据(把包裹交给码头)
4.调用close方法,释放资源(关闭码头)

举例

//发送端
public class Receiver {
    public static void main(String[] args) throws IOException {

            //创建DatagramSocket对象(找码头)
            DatagramSocket ds = new DatagramSocket(9999);

            //创建DatagramPacket对象(空包裹)
            byte[] bytes = new byte[1024];
            DatagramPacket dp = new DatagramPacket(bytes,bytes.length);

        while (true) {
            //接收数据(把接收到的数据装到包裹里)
            ds.receive(dp);

            //解析包裹(拆包)
            byte[] data = dp.getData();
            int length = dp.getLength();

            //通过数组和长度转换为一个字符串
            String s = new String(data,0,length);

            //获取IP地址并打印结果
            InetAddress address = dp.getAddress();
            System.out.println(address+"....."+s);
        }


        //释放资源(交钱走人)
        //ds.close();
    }
}

//接收端
public class Sender {
    public static void main(String[] args) throws IOException {
        //创建DatagramSocket对象(码头)
        DatagramSocket ds = new DatagramSocket();

        //创建DategramPacket读写(包裹)
        //需要发送的数据
        //Scanner sc = new Scanner(System.in);
        String[] arr = {
                "你问我爱你有多深,我爱你有几分",
                "我的情也真,我的爱也真",
                "月亮代表我的心",
                "你问我爱你有多深,我爱你有几分",
                "我的情不移,我的爱不变",
                "轻轻的一个吻,已经打动我的心",
                "深深的一段情,教我思念到如今",
                "你问我爱你有多深,我爱你有几分",
                "你去想一想,你去看一看",
                "月亮代表我的心",
                "轻轻的一个吻,已经打动我的心",
                "深深的一段情,教我思念到如今",
                "你问我爱你有多深,我爱你有几分",
                "你去想一想,你去看一看",
                "月亮代表我的心",
                "你去想一想,你去看一看",
                "月亮代表我的心"};
        //int a=0;
        //while (a<arr.length){
            //发送的信息
            //System.out.println("请输入你要发的数据:");
            byte[] bytes=null;
            for (int i = 0; i < arr.length; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                bytes = arr[i].getBytes();
                //byte[] bytes = sc.next().getBytes();
                //IP地址
                InetAddress ip = InetAddress.getByName("127.0.0.1");//主机本机的IP地址
                //端口号
                int port = 9999;
                DatagramPacket dp = new DatagramPacket(bytes,bytes.length,ip,port);

                //发送包裹
                ds.send(dp);
            }


            //释放资源
            //ds.close();
            //a++;
        //}

    }
}

三种通信方式

单播: 一个发送端 发给 一个接收端
使用DatagramSocket进行发送和接收

组播: 一个发送端 发给 多个接收端(一组)
//创建MulticastSocket对象
MulticastSocket ms=new MulticastSocket(10000);
//把当前地址加入组: 组播地址:224.0.1.0
ms.joinGroup(InetAddress.getByName(“224.0.1.0”));

广播: 一个发送端 发给 所有接收端
//广播地址:255.255.255.255
使用DatagramSocket进行发送和接收

TCP通信

TCP: 面向有连接,安全的协议,传输数据的大小没有限制。
1.创建Socket对象指定服务端ip地址和端口号
2.调用socket.getOutputStream()方法请求服务端
3.释放资源close();`

//客户端
public class Client {
    public static void main(String[] args) throws IOException {
        //创建Socket对象(客户端对象),指定服务端的ip地址和端口号
        Socket socket = new Socket("127.0.0.1",10086);

        //先发送数据个服务端(请求)
        OutputStream out = socket.getOutputStream();
        String[] arr = getStrings();

        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));
        for (int i = 0; i < arr.length; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            bw.write(arr[i]);
            bw.newLine();
            bw.flush();
        }
        //给服务器一个结束标记,告诉服务器写完了
        socket.shutdownOutput();
        InputStream in = socket.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        String line;
        while ((line=br.readLine())!=null){
            System.out.println(line);
        }


        //释放资源
        socket.close();
        bw.close();
        br.close();
//        for (int i = 0; i < arr.length; i++) {
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            byte[] bytes = arr[i].getBytes();
//            out.write(bytes);
//        }

        //在接收服务端返回的数据(响应)
       /* InputStream in = socket.getInputStream();
        byte[] by = new byte[1024];
        int len = in.read(by);
        String s = new String(by,0,len);

        System.out.println("服务端返回的数据:"+s);*/
    }

    private static String[] getStrings() {
        String[] arr = {
                "你问我爱你有多深,我爱你有几分",
                "我的情也真,我的爱也真",
                "月亮代表我的心",
                "你问我爱你有多深,我爱你有几分",
                "我的情不移,我的爱不变",
                "轻轻的一个吻,已经打动我的心",
                "深深的一段情,教我思念到如今",
                "你问我爱你有多深,我爱你有几分",
                "你去想一想,你去看一看",
                "月亮代表我的心",
                "轻轻的一个吻,已经打动我的心",
                "深深的一段情,教我思念到如今",
                "你问我爱你有多深,我爱你有几分",
                "你去想一想,你去看一看",
                "月亮代表我的心",
                "你去想一想,你去看一看",
                "月亮代表我的心"};
        return arr;
    }
}

//服务端
public class Server {
    public static void main(String[] args) throws IOException {
        //创建ServerSocket对象
        ServerSocket server = new ServerSocket(10086);


        //使用accept方法,监听客户端(那个客户端连接就获取那个客户端对象)
        Socket socket = server.accept();//阻塞

        //在通过Socket的getInputStream方法获取输入流,读取数据

        InputStream in = socket.getInputStream();
//        int a = 0;
//        while ((a = in.read()) != -1) {
//            byte[] bt = new byte[1024];
//            int len = in.read(bt);
//            String s = new String(bt, 0, len);
//
//            System.out.println("服务器接收的数据:" + s);
//        }
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        String line;
        while ((line=br.readLine())!=null){
            System.out.println(line);
        }
        //给服务器一个结束标记,告诉服务器读完了
        socket.shutdownInput();

        //在通过Socket的getOutputStream方法获取输出流,写出数据
        OutputStream out = socket.getOutputStream();
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));
        bw.write("接收成功");
        bw.newLine();
        bw.flush();
        //释放资源
        socket.close();
        server.close();
        bw.close();
        br.close();

    }
}

图片上传多线程案例

//客户端
public class Client {
    public static void main(String[] args) throws IOException {

            //创建socket对象
            Socket socket = new Socket("127.0.0.1",6666);
            //本地流  用来读取本地文件
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E:\\图片\\QQ图片20180829091757.jpg"));
            //BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("E:\\图片\\超智能足球\\ca384066d01609243c2839d2d80735fae7cd342b.jpg")));
            //网络流  写进服务器
            //BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            BufferedOutputStream bot = new BufferedOutputStream(socket.getOutputStream());
            int len;
            while ((len = bis.read())!=-1){
                bot.write(len);
            }
            //告诉服务端数据写完了
            socket.shutdownOutput();

            //获取服务端返回的数据
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String s = br.readLine();
            System.out.println(s);


        //释放资源
        socket.close();



    }
}

//线程启动
public class Server {
    public static void main(String[] args) throws IOException {
        //创建服务端ServerSocket对象,绑定端口号
        ServerSocket socket = new ServerSocket(6666);

        while (true) {
            //监听客户端
            Socket accept = socket.accept();
            new Thread(new ServerRunnable(accept)).start();

        }
        //socket.close();


    }
}

//服务端
public class ServerRunnable implements Runnable{
   private Socket accept;

    public ServerRunnable(Socket accept) {
        this.accept = accept;
    }

    @Override
    public void run() {
        try {
            //从客户端读取数据  网络中的流
            BufferedInputStream bis = new BufferedInputStream(accept.getInputStream());
            //BufferedReader br = new BufferedReader(new InputStreamReader(accept.getInputStream()));

            //把网络中的流写入本地  本地流
            String s = UUID.randomUUID().toString();
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:\\Users\\ZhangXM\\Desktop\\File\\"+s+".jpg"));
            //BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("C:\\Users\\ZhangXM\\Desktop\\File\\"+s+".jpg")));
            int len;
            while((len = bis.read())!=-1){
                bos.write(len);
            }
            bos.close();


            //往客户端返回提示信息
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));
            bw.write("上传成功");
            bw.newLine();
            bw.flush();
            bw.close();

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

        }
    }
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值