java语言之网络编程

java语言之网络编程


一、什么是网络

(1)概念

由点和线构成,表示诸多对象间的相互联系。

(2)计算机网络

为实现资源共享和信息传递,通过通信线路连接起来的若干主机(Host)。

(3)OSI参考模型

在这里插入图片描述

每层功能:

  • 第七层:应用层负责文件访问和管理、可靠运输服务、远程操作服务。(HTTP、FTP、SMTP)。
  • 第六层:表示层负责定义转换数据格式及加密,允许选择以二进制或ASCII格式传输。
  • 第五层:会话层负责使应用建立和维持会话,使通信在失效时继续恢复通信。(断点续传)。
  • 第四层:传输层负责是否选择差错恢复协议、数据流重用、错误顺序重排。(TCP、UDP)。
  • 第三层:网络层负责定义了能够标识所有网络节点的逻辑地址。(IP地址)。
  • 第二层:链路层在物理层上,通过规程或协议(差错控制)来控制传输数据的正确性。(MAC)。
  • 第一层:物理层为设备之间的数据通信提供传输信号和物理介质。(双绞线、光导纤维)。
(4)TCP/IP模型

在这里插入图片描述

每层功能:

  • 第四层:应用层负责传送各种最终形态的数据,是直接与用户打交道的层,典型协议是HTTP、FTP等。
  • 第三层:传输层负责传送文本数据,主要协议是TCP、UDP协议。
  • 第二层:网络层负责分配地址和传送二进制数据,主要协议是IP协议。
  • 第一层:接口层负责建立电路连接,是整个网络的物理基础,典型的协议包括以太网、ADSL等等。

二、TCP和UDP

(1)TCP:传输控制协议

是一种面向连接的、可靠的、基于字节流的传输层通信协议。数据大小无限制。建立连接的过程需要三次握手,断开连接的过程需要四次挥手。

(2)UDP:用户数据报协议

是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,每个包的大小64KB。


三、Socket编程

(1)Socket(套接字)是网络中的一个通信节点。
(2)分为客户端Socket与服务器ServerSocket。
(3)通信要求:IP地址 + 端口号。

(1)TCP实现客户端与服务器之间的一对一通信

案例演示1:一对一聊天,通信不断
Server类:
public class Server {
    public static void main(String[] args) throws IOException {
        //1、创建ServerSocket对象并指定端口号
        ServerSocket server = new ServerSocket(2007);
        System.out.println("服务端启动成功!");
        //2、调用accept(),接收客户端请求,阻塞方法(如果没有客户端请求,则阻塞)
        Socket socket = server.accept();
        System.out.println("客户端连接成功!");
        Scanner scanner = new Scanner(System.in);
        OutputStream os = null;
        InputStream is = null;
        try {
            while (true) {
                //3、获取输入流,读取客户端发送的数据
                is = socket.getInputStream();
                byte[] b = new byte[1024];
                int len = is.read(b);
                //4、将客户端发送的数据输出到控制台
                System.out.println("客户端:" + new String(b, 0, len));

                //5、获取输出流,发送数据给客户端
                os = socket.getOutputStream();
                os.write(scanner.next().getBytes());
            }
        }finally {
            os.close();
            is.close();
        }
    }
}
Client类:
public class Client {
    public static void main(String[] args) throws IOException {
        //1、创建Socket对象,并指定服务端的ip和端口号
        Socket socket = new Socket("127.0.0.1",2007);
        Scanner scanner = new Scanner(System.in);
        OutputStream os = null;
        InputStream is = null;
        try{
            while (true){
                //2、获取输出流,发送数据给服务端端
                os = socket.getOutputStream();
                os.write(scanner.next().getBytes());

                //3、获取输入流,读取服务端发送的数据
                is = socket.getInputStream();
                byte[] b = new byte[1024];
                int len = is.read(b);
                //4、将服务端发送的数据输出到控制台
                System.out.println("服务端:" + new String(b,0,len));
            }
        }finally {
            os.close();
            is.close();
        }
    }
}
案例演示2:利用线程实现读写不冲突
Server类:
public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(8888);
        System.out.println("服务端开启成功!");
        Socket socket = server.accept();
        System.out.println("客户端连接成功!");
        new ReaderThread("客户端",socket).start();
        new WriterThread("服务端",socket).start();
    }
}
Client类:
public class Client2 {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1",8888);
        new ReaderThread("服务端",socket).start();
        new WriterThread("客户端",socket).start();
    }
}
ReaderThread线程类:
public class ReaderThread extends Thread {
    private Socket socket;
    private String name;
    public ReaderThread(String name, Socket socket){
        this.name = name;
        this.socket = socket;
    }
    @Override
    public void run() {
        InputStream is = null;
        try {
            is = socket.getInputStream();
            byte[] b = new byte[1024];
            while (true) {
                int len = is.read(b);
                System.out.println(new String(b, 0, len));
            }
        } catch (IOException e) {
            System.out.println(name + "已关闭!");
        } finally {
            try {
                is.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
WriterThread线程类:
public class WriterThread extends Thread {
    private String name;
    private Socket socket;
    Scanner scanner = new Scanner(System.in);
    public WriterThread(String name, Socket socket){
        this.name = name;
        this.socket = socket;
    }
    @Override
    public void run() {
        OutputStream os = null;
        try {
            os = socket.getOutputStream();
            while (true) {
                os.write((name+":"+scanner.next()).getBytes());
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                os.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
案例演示3:字符流一对一通信,读写不冲突
Server类:
public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(8888);
        System.out.println("服务端开启成功!");
        Socket socket = server.accept();
        System.out.println("客户端连接成功!");
        new ReaderThread("客户端",socket).start();
        new WriterThread("服务端",socket).start();
    }
}
Client类:
public class Client2 {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1",8888);
        new ReaderThread("服务端",socket).start();
        new WriterThread("客户端",socket).start();
    }
}
ReaderThread线程类:
public class ReaderThread1 extends Thread {
    private String name;
    BufferedReader br;
    public ReaderThread1(String name,Socket socket) throws IOException {
        br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        this.name = name;
    }
    @Override
    public void run() {
        String str = null;
        try {
            while(true){
                str = br.readLine();
                if(str != null){
                    System.out.println(str);
                }
            }
        } catch (IOException e) {
            System.out.println(name + "已关闭!");
        }finally {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
WriterThread线程类:
public class WriterThread1 extends Thread {
    private String name;
    BufferedWriter bw;
    BufferedReader br;
    public WriterThread1(String name,Socket socket) throws IOException {
        bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        br = new BufferedReader(new InputStreamReader(System.in));
        this.name = name;
    }
    @Override
    public void run() {
        try {
            while (true) {
                bw.write(name + ":" + br.readLine());
                bw.newLine();
                bw.flush();
            }
        } catch (IOException e) {
            System.out.println(name + "已关闭!");
        }finally {
            try {
                bw.close();
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

(2)UDP实现客户端与服务器之间的一对一通信

案例演示1:一对一聊天,通信不断
Client1类:
public class Client1 {
    public static void main(String[] args) throws Exception {
        Scanner scanner = new Scanner(System.in);
        //创建一个指定端口号的 UDP 套接字
        DatagramSocket socket = new DatagramSocket(8888);
        while (true) {
            //发送数据给其他主机
            //把数据保存在数组中
            byte[] b = scanner.next().getBytes();
            //创建DatagramPacket对象,里面的参数为(数组,数组的长度,接收的主机IP,接收的主机端口号)
            DatagramPacket packet = new DatagramPacket(b, b.length, InetAddress.getByName("127.0.0.1"), 9999);
            //开始发送
            socket.send(packet);

            //接收其他主机发送过来的数据
            //先创建存放数据的数组和DatagramPacket对象
            b = new byte[1024];
            packet = new DatagramPacket(b,b.length);
            //接收数据
            socket.receive(packet);
            //解析数据并输出
            System.out.println("Client2:" + new String(packet.getData(),0, packet.getLength()));
        }
    }
}
Client2类:
public class Client2 {
    public static void main(String[] args) throws Exception {
        Scanner scanner = new Scanner(System.in);
        //创建一个指定端口号的 UDP 套接字
        DatagramSocket socket = new DatagramSocket(9999);
        while (true) {
            //接收其他主机发送过来的数据
            //先创建存放数据的数组和DatagramPacket对象
            byte[] b = new byte[1024];
            DatagramPacket packet = new DatagramPacket(b, b.length);
            //接收数据
            socket.receive(packet);
            //解析数据并输出
            System.out.println("Client1:" + new String(packet.getData(), 0, packet.getLength()));

            //发送数据给其他主机
            //把数据保存在数组中
            b = scanner.next().getBytes();
            //创建DatagramPacket对象,里面的参数为(数组,数组的长度,接收的主机IP,接收的主机端口号)
            packet = new DatagramPacket(b, b.length, InetAddress.getByName("127.0.0.1"), 8888);
            //开始发送
            socket.send(packet);
        }
    }
}
案例演示2:利用线程实现读写不冲突
Client3类:
public class Client3 {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(8888);
        Scanner scanner = new Scanner(System.in);
        new ReadThread(socket,"Client4说").start();
        new WriteThread(socket,"127.0.0.1",9999).start();
    }
}
Client4类:
public class Client4 {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(9999);
        Scanner scanner = new Scanner(System.in);
        new ReadThread(socket,"Client3说").start();
        new WriteThread(socket,"127.0.0.1",8888).start();
    }
}
ReadThread线程类:
public class ReadThread extends Thread {
    DatagramSocket socket;
    String name;
    public ReadThread(DatagramSocket socket,String name) {
        this.socket = socket;
        this.name = name;
    }
    @Override
    public void run() {
        try {
            while (true) {
                byte[] b = new byte[1024];
                DatagramPacket packet = new DatagramPacket(b, b.length);
                socket.receive(packet);
                System.out.println(name + ":" + new String(packet.getData(), 0, packet.getLength()));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
WriteThread线程类:
public class WriteThread extends Thread {
    DatagramSocket socket;
    String ip;
    int duankou;
    public WriteThread(DatagramSocket socket,String ip,int duankou) {
        this.ip = ip;
        this.duankou = duankou;
        this.socket = socket;
    }
    @Override
    public void run() {
        Scanner scanner = new Scanner(System.in);
        try {
            while (true) {
                byte[] b = scanner.next().getBytes();
                DatagramPacket packet = new DatagramPacket(b, b.length, InetAddress.getByName(ip), duankou);
                socket.send(packet);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值