开发者社区> 黑夜路口> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

05.Java网络编程(代码实践)

简介: 计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路链接起来,在网络操作系统,网络管理软件及网络通信协议的协调下,实现资源贡献和信息传递的计算机系统 网络编程就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换 网...
+关注继续查看

计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路链接起来,在网络操作系统,网络管理软件及网络通信协议的协调下,实现资源贡献和信息传递的计算机系统

网络编程就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换

网络编程三要素:

IP:每个设备在网络中的唯一标识,每台网络终端在网络中都有一个独立的地址,我们在网络中传输数据就是使用这个地址
ipconfig:查看本机IP地址,ipv4地址
ping:测试连接

端口:每个程序在设备上的唯一标识,每个网络程序都需要绑定一个端口号,传输数据的时候除了确定发送到哪台机器上,还需要确定发送到哪个程序,端口号范围:0~65535,编写的网络应用端口号尽量设置1024以上的,1024之下的基本上都被系统程序占用了

协议:为计算机网络进行数据交换而建立的规则,标准或约定的集合
UDP:面向无连接,数据不安全,速度快,不区分客户端与服务端
TCP:面向链接,三次握手,数据安全但效率低,分为客户端和服务端,三次握手的过程,客户端向服务端发起请求,服务端响应请求,传输数据

Socke套接字通信:

网络上具有唯一标识的IP地址和端口号组合在一起,才能构成唯一能识别的标识符套接字
通信的两端都有socket,网络通信其实就是socket间的通信,它通过IO流进行传输,Socket在应用程序中创建,通过一种绑定机制与驱动机制建立关系,告诉自己所对应的IP和端口

新建一个Java工程模拟UDP通信


img_267f1b14280c52d012826235fc855759.png
图片1.png
package com.ren.socket;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
/**
 * socket好比发货的码头,packet就是需要发送的集装箱货物,这个货物需要发送到哪里,它的地址
 * 信息是在货物上标明的,所以packet构造方法上传递了发送目的地的地址和该地址上接收程序的端口
 * @author renzhenming
 *
 */
public class Send {

    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        DatagramSocket socket = new DatagramSocket();
        
        while(true){
            String scan = sc.nextLine();
            DatagramPacket packet = 
                    new DatagramPacket(scan.getBytes(), //或者用127.0.0.1也可以
                            scan.getBytes().length, InetAddress.getByName("192.168.1.103"), 9999);
            socket.send(packet);
        }
    }

}
package com.ren.socket;

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

/**
 * 创建接收端
 * @author renzhenming
 *
 */
public class Receive {

    public static void main(String[] args) throws IOException {
        //用于接收传递过来的数据
        DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);
        //指定端口号,用于接收指定端口传递的数据
        DatagramSocket socket = new DatagramSocket(9999);
        
        while(true){
            //执行之后会将接收到的数据放在packet中
            socket.receive(packet);
            //转换成字符串打印
            byte[] arr = packet.getData();
            int len = packet.getLength();
            String ip = packet.getAddress().getHostAddress();
            int port = packet.getPort();
            System.out.println(ip+":"+port+":"+new String(arr,0,len));
        }
    }
}

为了演示效果,我们打开两个命令行,在命令行中分别执行这两个Java方法,先执行Receive端,注意要在bin目录下运行命令


img_cfa1932858998c475d6890b2dc849f0c.png
图片1.png

开启线程执行

package com.ren.socket;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;
/**
 * socket好比发货的码头,packet就是需要发送的集装箱货物,这个货物需要发送到哪里,它的地址
 * 信息是在货物上标明的,所以packet构造方法上传递了发送目的地的地址和该地址上接收程序的端口
 * @author renzhenming
 *
 */
public class SocketDemo {

    public static void main(String[] args) throws IOException {
        new Receive().start();
        new Sender().start();
    }
}

class Receive extends Thread{
    @Override
    public void run() {
        super.run();
        try {
            //用于接收传递过来的数据
            DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);
            //指定端口号,用于接收指定端口传递的数据
            DatagramSocket socket = new DatagramSocket(9999);
                    
            while(true){
                //执行之后会将接收到的数据放在packet中
                socket.receive(packet);
                //转换成字符串打印
                byte[] arr = packet.getData();
                int len = packet.getLength();
                String ip = packet.getAddress().getHostAddress();
                int port = packet.getPort();
                System.out.println(ip+":"+port+":"+new String(arr,0,len));
            }
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class Sender extends Thread{
    @Override
    public void run() {
        super.run();
        try {
            Scanner sc = new Scanner(System.in);
            DatagramSocket socket = new DatagramSocket();
            
            while(true){
                String scan = sc.nextLine();
                DatagramPacket packet = 
                        new DatagramPacket(scan.getBytes(), //或者用127.0.0.1也可以
                                scan.getBytes().length, InetAddress.getByName("192.168.1.103"), 9999);
                socket.send(packet);
            }
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

新建一个Java工程模拟TCP通信
TCP协议的Socket通信,客户端通过Socket处理发送和接收,服务端通过ServerSocket 处理发送和接收

Socket_TCP_Client

package com.ren.socket;

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.net.UnknownHostException;

public class Socket_TCP_Client {

    public static void main(String[] args) throws UnknownHostException, IOException {
        //socket1();
        socket2();
    }
    //多个
    private static void socket2() throws UnknownHostException, IOException {
        Socket socket = new Socket("127.0.0.1",12345);
        BufferedReader br = new BufferedReader
                (new InputStreamReader(socket.getInputStream()));
        PrintStream ps = new PrintStream(socket.getOutputStream());
        
        System.out.println(br.readLine());
        ps.println("我可以去哪里逛逛呢");
        System.out.println(br.readLine());
        ps.println("谢谢");
        socket.close();
        
    }

    //一次读取一个
    private static void socket1() throws UnknownHostException, IOException {
        Socket socket = new Socket("127.0.0.1",12345);
        //输入流可以读取服务端输出流写出的数据
        InputStream in = socket.getInputStream();
        //输出流可以写出数据到服务端输入流
        OutputStream out = socket.getOutputStream();
        out.write("打开百度首页".getBytes());
        byte[] arr = new byte[1024];
        int len = in.read(arr);
        System.out.println("收到服务端数据:"+new String(arr,0,len));
    }

}

Socket_TCP_Server

package com.ren.socket;

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 Socket_TCP_Server {

    public static void main(String[] args) throws Exception {
        //socket1();
        //socket2();
        socket3();
    }
    //多线程开启服务器,可以接收多个客户端来咨询
    private static void socket3() throws IOException {
        final ServerSocket serverSocket = new ServerSocket(12345);
        
        while(true){
            new Thread(new Runnable() {
                
                @Override
                public void run() {
                    
                    try {
                        Socket socket = serverSocket.accept();
                        BufferedReader br = new BufferedReader
                                (new InputStreamReader(socket.getInputStream()));
                        PrintStream ps = new PrintStream(socket.getOutputStream());
                        
                        ps.println("欢迎来到中国");
                        //readLine是以换行为结束符读取一行数据的,如果客户端写入数据的时候使用了print而不是println,就会导致
                        //数据无法读取
                        System.out.println(br.readLine());
                        ps.println("你可以先去游览北京长城");
                        System.out.println(br.readLine());
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
        
        
    }

    //实现多次读取
    private static void socket2() throws Exception {
        ServerSocket serverSocket = new ServerSocket(12345);
        Socket socket = serverSocket.accept();
        
        BufferedReader br = new BufferedReader
                (new InputStreamReader(socket.getInputStream()));
        PrintStream ps = new PrintStream(socket.getOutputStream());
        
        ps.println("欢迎来到中国");
        //readLine是以换行为结束符读取一行数据的,如果客户端写入数据的时候使用了print而不是println,就会导致
        //数据无法读取
        System.out.println(br.readLine());
        ps.println("你可以先去游览北京长城");
        System.out.println(br.readLine());
        socket.close();

    }

    //实现单词读取
    private static void socket1() throws IOException {
        //注意端口号不能超过65535
        ServerSocket server = new ServerSocket(12345);
        //接收服务端数据,这个操作会阻塞线程,直到收到数据才往下执行
        Socket socket = server.accept();
        //接收到的客户端消息
        InputStream is = socket.getInputStream();
        byte[] arr = new byte[1024];
        int len = is.read(arr);
        System.out.println("收到客户端数据:"+new String(arr,0,len));
        //向客户端发送消息需要获取一个输入流然后write
        OutputStream os = socket.getOutputStream();
        os.write("百度一下,你就知道".getBytes());
    }

}

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
线程 - Java 多线程编程(下)
线程 - Java 多线程编程(下)
30 0
线程 - Java 多线程编程(上)
线程 - Java 多线程编程(上)
80 0
Java多线程那些事,对Java并发编程2w余字的总结,超详细(从入门到完全掌握)
Java多线程那些事,对Java并发编程2w余字的总结,超详细(从入门到完全掌握)
95 0
java多线程中的死锁、活锁、饥饿、无锁都是什么鬼?
死锁、活锁、饥饿是关于多线程是否活跃出现的运行阻塞障碍问题,如果线程出现了这三种情况,即线程不再活跃,不能再正常地执行下去了。
77 0
五分钟带你玩转多线程(一)java多线程基础知识简介
线程概念 进程:是一个执行中的程序,如打开网易云音乐,网易云音乐就是一个进程 线程:是进程的组成,一个进程包含多个线程,是jvm最小调度单元。如网易云音乐听歌是一个线程,评价是一个线程。
56 0
Java的并发编程中的多线程问题到底是怎么回事儿?
原创: Hollis 在我之前的一篇《再有人问你Java内存模型是什么,就把这篇文章发给他。》文章中,介绍了Java内存模型,通过这篇文章,大家应该都知道了Java内存模型的概念以及作用,这篇文章中谈到,在Java并发编程中,通常会遇到三个问题,即原子性问题、一致性问题和有序性问题。
1060 0
Java网络编程-NIO
构造函数 首先放一个NIO的使用流程 1、创建ServerSocketChannel,配置为非阻塞模式 2、绑定监听,配置TCP参数,例如backlog大小; 3、创建一个独立的I...
810 0
+关注
黑夜路口
安卓高级工程师,目前任职于Wifi万能钥匙
152
文章
1
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载