当前位置:   ASP > 正文

Java中TCP通信的实现_java tcp发送报文

java tcp发送报文

0、TCP通信

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流传输层通信协议

如果使用了 WireShark 工具,可以看到一次TCP连接建立时的整个过程。

1、单向通信

单向通信中,一方固定为信息发送方,另外一方则固定为信息的接收方。

1.1 单向通信中的服务端

服务端即为信息的接收方。

使用 ServerSocket 类创建服务端,并将服务的端口设置为 9527;

serverSocket.accept() 方法用于监听对 9527 端口的连接,该方法为阻塞式方法,当接收到数据后,程序才会继续向下执行,否则一直处于等待状态;

当接收到数据后,因是使用字节流传输,这里使用 使用 InputStreamReader 的转换流将字节数据转换为字符串,并使用 BufferedReader 进行读取和输出;

当服务端接收到客户端的请求后,需要向客户端发出响应数据,使用 PrintWriter 发送响应报文,需要使用 flush() 方法,将消息发出;

当客户端发出的消息为“再见”时,服务端即退出通信,关闭服务。

  1. import java.io.*;
  2. import java.net.ServerSocket;
  3. import java.net.Socket;
  4. public class Server {
  5. public static void main(String[] args) {
  6. System.out.println("服务器启动!");
  7. try {
  8. ServerSocket serverSocket = new ServerSocket(9527);
  9. Socket socket = serverSocket.accept();
  10. BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  11. PrintWriter pw = new PrintWriter(socket.getOutputStream());
  12. System.out.println("接收客户端消息");
  13. while (true){
  14. String in = br.readLine();
  15. System.out.println("接收到客户端发来的请求:" + in);
  16. if("再见".equals(in)){
  17. break;
  18. }
  19. pw.print(in + "回报");
  20. pw.flush();
  21. }
  22. } catch (IOException e) {
  23. System.out.println("服务启动失败!");
  24. e.printStackTrace();
  25. }
  26. }
  27. }

启动后,服务端输出为:

服务器启动!

1.2 单向通信中的客户端

客户端即为信息的发送方。

  • 创建 Socket 对象,​​Socket("localhost", 9527)​​ 和端口为 9527 的服务建立通信;
  • 接收和发送消息的方法,和服务端相同;
  • 为了能够向服务端循环发送消息,使用了死循环,当用户输入“再见”时,终止循环;
  • 使用 Scanner 对象接收键盘输入。

  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.io.InputStreamReader;
  4. import java.io.PrintWriter;
  5. import java.net.Socket;
  6. import java.util.Scanner;
  7. public class Client {
  8. public static void main(String[] args) {
  9. try {
  10. Socket socket = new Socket("localhost", 9527);
  11. //读取输入流
  12. BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  13. //获取输出流
  14. PrintWriter pw = new PrintWriter(socket.getOutputStream());
  15. //从键盘获取输入
  16. Scanner scanner = new Scanner(System.in);
  17. while (true){
  18. //从控制台获取向服务端发送的消息
  19. String next = scanner.next();
  20. pw.println(next);
  21. pw.flush();
  22. String s = br.readLine();
  23. System.out.println("收到服务器响应:" + s);
  24. if("再见".equals(next)){
  25. break;
  26. }
  27. }
  28. } catch (IOException e) {
  29. e.printStackTrace();
  30. }
  31. }
  32. }

1.3 建立通信

启动客户端后,并在客户端的控制台输入“你好”,观察服务端和客户端的控制台

在客户端的控制台输入“再见”,观察服务端和客户端的控制台

2、双向通信

双向通信中,双方都可以既是信息的发送方,也可以是信息的接收方。

2.1 双向通信中的服务端

在服务端设置发消息和收消息。

在服务端也使用了 Scanner ,用来接收控制台输入,并将其发送给客户端。

  1. import java.io.BufferedReader;
  2. import java.io.InputStreamReader;
  3. import java.io.PrintWriter;
  4. import java.net.ServerSocket;
  5. import java.net.Socket;
  6. import java.util.Scanner;
  7. public class Server {
  8. public static void main(String[] args) {
  9. try{
  10. ServerSocket serverSocket = new ServerSocket(9528);
  11. Socket socket = serverSocket.accept();
  12. //获取客户端请求
  13. BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  14. //获取键盘输入
  15. Scanner scanner = new Scanner(System.in);
  16. //发送消息到客户端
  17. PrintWriter pw = new PrintWriter(socket.getOutputStream());
  18. while (true){
  19. String input = br.readLine();
  20. System.out.println("收到客户端请求: " + input);
  21. String output = scanner.nextLine();
  22. pw.println(output);
  23. pw.flush();
  24. if("再见".equals(input)){
  25. break;
  26. }
  27. }
  28. }catch (Exception e){
  29. e.printStackTrace();
  30. System.out.println("服务启动失败!");
  31. }
  32. }
  33. }

2.2 双向通信中的客户端

在客户端设置发消息和收消息

  1. import java.io.BufferedReader;
  2. import java.io.InputStreamReader;
  3. import java.io.PrintWriter;
  4. import java.net.Socket;
  5. import java.util.Scanner;
  6. public class Client {
  7. public static void main(String[] args) {
  8. try{
  9. Socket socket = new Socket("127.0.0.1", 9528);
  10. //获取服务端响应
  11. BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  12. //获取客户端用户输入
  13. Scanner scanner = new Scanner(System.in);
  14. //向服务端发送请求
  15. PrintWriter pw = new PrintWriter(socket.getOutputStream());
  16. System.out.println("准备接收请求……");
  17. while (true){
  18. String output = scanner.next();
  19. pw.println(output);
  20. pw.flush();
  21. String input = br.readLine();
  22. System.out.println("来自服务端的响应: " + input);
  23. if("再见".equals(output)){
  24. break;
  25. }
  26. }
  27. }catch (Exception e){
  28. e.printStackTrace();
  29. }
  30. }
  31. }

2.3 建议通信

启动服务端及客户端,并在控制台输入内容:

存在的问题:

这样的通信,需要客户端发一次消息 -》 服务端回一次消息,如果客户端同时发送两条消息,就会导致消息不同步。

比如下边的情况:

这个问题可以先思考下,应该如何解决,后边将会给出解决方案。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/blog/ASP/detail/38117
推荐阅读
相关标签
  

闽ICP备14008679号