【JavaSE】Java基础语法(四十五):TCP UDP 全解

简介: 1. TCP发送数据Java中的TCP通信Java对基于TCP协议的的网络提供了良好的封装,使用Socket对象来代表两端的通信端口,并通过Socket产生IO流来进行网络通信。Java为客户端提供了Socket类,为服务器端提供了ServerSocket类

1. TCP发送数据

  • Java对基于TCP协议的的网络提供了良好的封装,使用Socket对象来代表两端的通信端口,并通过Socket产生IO流来进行网络通信。
  • Java为客户端提供了Socket类,为服务器端提供了ServerSocket类

ab66bd537e58482188832fb39bf9fcfa.png

相关方法

be32e43d27a04943b0960ef1fb46571d.png

  • 示例代码
public class ClientDemo {
  public static void main(String[] args) throws IOException {
    //创建客户端的Socket对象(Socket)
    //Socket(String host, int port) 创建流套接字并将其连接到指定主机上的指定端口号
    Socket s = new Socket("127.0.0.1",10000);
    //获取输出流,写数据
    //OutputStream getOutputStream() 返回此套接字的输出流
    OutputStream os = s.getOutputStream();
    os.write("hello,tcp,我来了".getBytes());
    //释放资源
    s.close();
  }
}

2. TCP接收数据【应用】

  • 构造方法: 创建绑定到指定端口的服务器套接字
ServletSocket(int port)


  • 相关方法:监听要连接到此的套接字并接受它
Socket accept()


注意事项


accept方法是阻塞的,作用就是等待客户端连接

客户端创建对象并连接服务器,此时是通过三次握手协议,保证跟服务器之间的连接

针对客户端来讲,是往外写的,所以是输出流

针对服务器来讲,是往里读的,所以是输入流

read方法也是阻塞的

客户端在关流的时候,还多了一个往服务器写结束标记的动作

最后一步断开连接,通过四次挥手协议保证连接终止

  • 三次握手
  • 四次挥手

3. TCP程序练习

案例需求

客户端:发送数据,接受服务器反馈

服务器:收到消息后给出反馈

案例分析

客户端创建对象,使用输出流输出数据

服务端创建对象,使用输入流接受数据

服务端使用输出流给出反馈数据

客户端使用输入流接受反馈数据

代码实现

// 客户端
public class ClientDemo {
  public static void main(String[] args) throws IOException {
    Socket socket = new Socket("127.0.0.1",10000);
    OutputStream os = socket.getOutputStream();
    os.write("hello".getBytes());
    // os.close();如果在这里关流,会导致整个socket都无法使用
    socket.shutdownOutput();//仅仅关闭输出流.并写一个结束标记,对socket没有任何
    影响
    BufferedReader br = new BufferedReader(new
    InputStreamReader(socket.getInputStream()));
    String line;
    while((line = br.readLine())!=null){
      System.out.println(line);
    }
    br.close();
    os.close();
    socket.close();
  }
}
// 服务器
public class ServerDemo {
  public static void main(String[] args) throws IOException {
    ServerSocket ss = new ServerSocket(10000);
    Socket accept = ss.accept();
    InputStream is = accept.getInputStream();
    int b;
    while((b = is.read())!=-1){
      System.out.println((char) b);
    }
    System.out.println("看看我执行了吗?");
    BufferedWriter bw = new BufferedWriter(new
    OutputStreamWriter(accept.getOutputStream()));
    bw.write("你谁啊?");
    bw.newLine();
    bw.flush();
    bw.close();
    is.close();
    accept.close();
    ss.close();
  }
}

4. TCP程序文件上传练习【应用】

案例需求

客户端:数据来自于本地文件,接收服务器反馈

服务器:接收到的数据写入本地文件,给出反馈

案例分析

- 创建客户端对象,创建输入流对象指向文件,每读一次数据就给服务器输出一次数据,输出

结束后使用shutdownOutput()方法告知服务端传输结束

- 创建服务器对象,创建输出流对象指向文件,每接受一次数据就使用输出流输出到文件中,

传输结束后。使用输出流给客户端反馈信息

- 客户端接受服务端的回馈信息

相关方法

6bf3938a584c4896b1ec46e65e9a6e60.png

代码实现

// 客户端
public class ClientDemo {
  public static void main(String[] args) throws IOException {
    Socket socket = new Socket("127.0.0.1",10000);
    //是本地的流,用来读取本地文件的.
    BufferedInputStream bis = new BufferedInputStream(new
    FileInputStream("socketmodule\\ClientDir\\1.jpg"));
    //写到服务器 --- 网络中的流
    OutputStream os = socket.getOutputStream();
    BufferedOutputStream bos = new BufferedOutputStream(os);
    int b;
    while((b = bis.read())!=-1){
      bos.write(b);//通过网络写到服务器中
    }
    bos.flush();
    //给服务器一个结束标记,告诉服务器文件已经传输完毕
    socket.shutdownOutput();
    BufferedReader br = new BufferedReader(new
    InputStreamReader(socket.getInputStream()));
    String line;
    while((line = br.readLine()) !=null){
      System.out.println(line);
    }
    bis.close();
    socket.close();
  }
}
// 服务器
public class ServerDemo {
  public static void main(String[] args) throws IOException {
    ServerSocket ss = new ServerSocket(10000);
    Socket accept = ss.accept();
    //网络中的流,从客户端读取数据的
    BufferedInputStream bis = new
    BufferedInputStream(accept.getInputStream());
    //本地的IO流,把数据写到本地中,实现永久化存储
    BufferedOutputStream bos = new BufferedOutputStream(new
    FileOutputStream("socketmodule\\ServerDir\\copy.jpg"));
    int b;
    while((b = bis.read()) !=-1){
      bos.write(b);
    }
    BufferedWriter bw = new BufferedWriter(new
    OutputStreamWriter(accept.getOutputStream()));
    bw.write("上传成功");
    bw.newLine();
    bw.flush();
    bos.close();
    accept.close();
    ss.close();
  }
}

5. UDP发送数据

  • Java中的UDP通信
  • UDP协议是一种不可靠的网络协议,它在通信的两端各建立一个Socket对象,但是这两个
    Socket只是发送,接收数据的对象,因此对于基于UDP协议的通信双方而言,没有所谓的客
    户端和服务器的概念
  • Java提供了DatagramSocket类作为基于UDP协议的Socket
  • 构造方法

484e31de366743faa5a4459193d76356.png

相关方法

  • 发送数据的步骤
    - 创建发送端的Socket对象(DatagramSocket)
    - 创建数据,并把数据打包
    - 调用DatagramSocket对象的方法发送数据
    - 关闭发送端

代码演示

public class SendDemo {
  public static void main(String[] args) throws IOException {
    //创建发送端的Socket对象(DatagramSocket)
    // DatagramSocket() 构造数据报套接字并将其绑定到本地主机上的任何可用端口
    DatagramSocket ds = new DatagramSocket();
    //创建数据,并把数据打包
    //DatagramPacket(byte[] buf, int length, InetAddress address, int port)
    //构造一个数据包,发送长度为 length的数据包到指定主机上的指定端口号。
    byte[] bys = "hello,udp,我来了".getBytes();
    DatagramPacket dp = new
    DatagramPacket(bys,bys.length,InetAddress.getByName("127.0.0.1"),10086);
    //调用DatagramSocket对象的方法发送数据
    //void send(DatagramPacket p) 从此套接字发送数据报包
    ds.send(dp);
    //关闭发送端
    //void close() 关闭此数据报套接字
    ds.close();
  }
}

6. UDP接收数据【应用】

  • 接收数据的步骤
  • 创建接收端的Socket对象(DatagramSocket)
  • 创建一个数据包,用于接收数据
  • 调用DatagramSocket对象的方法接收数据
  • 解析数据包,并把数据在控制台显示
  • 关闭接收端

构造方法

2a6d7ab624524099924d49fcb0c4cbcb.png

相关方法

f6bcd476025842ebba585381805a0c17.png示例代码

public class ReceiveDemo {
  public static void main(String[] args) throws IOException {
    //创建接收端的Socket对象(DatagramSocket)
    DatagramSocket ds = new DatagramSocket(12345);
    //创建一个数据包,用于接收数据
    byte[] bys = new byte[1024];
    DatagramPacket dp = new DatagramPacket(bys, bys.length);
    //调用DatagramSocket对象的方法接收数据
    ds.receive(dp);
    //解析数据包,并把数据在控制台显示
    System.out.println("数据是:" + new String(dp.getData(), 0,
    dp.getLength()));
    }
  }
}

7. UDP通信程序练习【应用】

  • 案例需求
  • UDP发送数据:数据来自于键盘录入,直到输入的数据是886,发送数据结束
  • UDP接收数据:因为接收端不知道发送端什么时候停止发送,故采用死循环接收

代码实现

/*
  UDP发送数据:
  数据来自于键盘录入,直到输入的数据是886,发送数据结束
*/
public class SendDemo {
  public static void main(String[] args) throws IOException {
    //创建发送端的Socket对象(DatagramSocket)
    DatagramSocket ds = new DatagramSocket();
    //键盘录入数据
    Scanner sc = new Scanner(System.in);
    while (true) {
      String s = sc.nextLine();
      //输入的数据是886,发送数据结束
      if ("886".equals(s)) {
        break;
      }
      //创建数据,并把数据打包
      byte[] bys = s.getBytes();
      DatagramPacket dp = new DatagramPacket(bys, bys.length,
      InetAddress.getByName("192.168.1.66"), 12345);
      //调用DatagramSocket对象的方法发送数据
      ds.send(dp);
    }
    //关闭发送端
    ds.close();
  }
}


/*
  UDP接收数据:
  因为接收端不知道发送端什么时候停止发送,故采用死循环接收
*/
public class ReceiveDemo {
  public static void main(String[] args) throws IOException {
    //创建接收端的Socket对象(DatagramSocket)
    DatagramSocket ds = new DatagramSocket(12345);
    while (true) {
      //创建一个数据包,用于接收数据
      byte[] bys = new byte[1024];
      DatagramPacket dp = new DatagramPacket(bys, bys.length);
      //调用DatagramSocket对象的方法接收数据
      ds.receive(dp);
      //解析数据包,并把数据在控制台显示
      System.out.println("数据是:" + new String(dp.getData(), 0,
      dp.getLength()));
    }
    //关闭接收端
    // ds.close();
  }
}

8. UDP三种通讯方式

  • 单播
    单播用于两个主机之间的端对端通信
  • 组播
    组播用于对一组特定的主机进行通信
  • 广播
    广播用于一个主机对整个局域网上所有主机上的数据通信

 

相关文章
|
2月前
|
Java Apache Maven
Java百项管理之新闻管理系统 熟悉java语法——大学生作业 有源码!!!可运行!!!
文章提供了使用Apache POI库在Java中创建和读取Excel文件的详细代码示例,包括写入数据到Excel和从Excel读取数据的方法。
64 6
Java百项管理之新闻管理系统 熟悉java语法——大学生作业 有源码!!!可运行!!!
|
2月前
|
Java 开发工具 Android开发
Kotlin语法笔记(26) -Kotlin 与 Java 共存(1)
本系列教程笔记详细讲解了Kotlin语法,适合需要深入了解Kotlin的开发者。若需快速学习Kotlin,建议查看“简洁”系列教程。本期重点介绍了Kotlin与Java的共存方式,包括属性、单例对象、默认参数方法、包方法、扩展方法以及内部类和成员的互操作性。通过这些内容,帮助你在项目中更好地结合使用这两种语言。
50 1
|
2月前
|
Java 开发工具 Android开发
Kotlin语法笔记(26) -Kotlin 与 Java 共存(1)
Kotlin语法笔记(26) -Kotlin 与 Java 共存(1)
35 2
|
20天前
|
Java
java do while 的语法怎么用?
java do while 的语法怎么用?
34 3
|
2月前
|
Java 编译器 Android开发
Kotlin语法笔记(28) -Kotlin 与 Java 混编
本系列教程详细讲解了Kotlin语法,适合需要深入了解Kotlin的开发者。对于希望快速学习Kotlin的用户,推荐查看“简洁”系列教程。本文档重点介绍了Kotlin与Java混编的技巧,包括代码转换、类调用、ProGuard问题、Android library开发建议以及在Kotlin和Java之间互相调用的方法。
31 1
|
2月前
|
安全 Java 编译器
Kotlin语法笔记(27) -Kotlin 与 Java 共存(二)
本教程详细讲解Kotlin语法,适合希望深入了解Kotlin的开发者。若需快速入门,建议查阅“简洁”系列教程。本文重点探讨Kotlin与Java共存的高级话题,包括属性访问、空安全、泛型处理、同步机制及SAM转换等,助你在项目中逐步引入Kotlin。
30 1
|
2月前
|
Java 编译器 Android开发
Kotlin语法笔记(28) -Kotlin 与 Java 混编
Kotlin语法笔记(28) -Kotlin 与 Java 混编
33 2
|
2月前
|
Java 程序员 编译器
在Java编程中,保留字(如class、int、for等)是具有特定语法意义的预定义词汇,被语言本身占用,不能用作变量名、方法名或类名。
在Java编程中,保留字(如class、int、for等)是具有特定语法意义的预定义词汇,被语言本身占用,不能用作变量名、方法名或类名。本文通过示例详细解析了保留字的定义、作用及与自定义标识符的区别,帮助开发者避免因误用保留字而导致的编译错误,确保代码的正确性和可读性。
59 3
|
2月前
|
JavaScript 安全 Java
谈谈UDP、HTTP、SSL、TLS协议在java中的实际应用
下面我将详细介绍UDP、HTTP、SSL、TLS协议及其工作原理,并提供Java代码示例(由于Deno是一个基于Node.js的运行时,Java代码无法直接在Deno中运行,但可以通过理解Java示例来类比Deno中的实现)。
81 1
|
2月前
|
安全 Java 编译器
Kotlin语法笔记(27) -Kotlin 与 Java 共存(二)
Kotlin语法笔记(27) -Kotlin 与 Java 共存(二)
34 0
下一篇
DataWorks