为什么TCP发送数据要经过字节流、打印流?而UDP发送竟然如此的简单?

首先是TCP的客户端的代码

        //1.创建客户端Socket,指定服务器端地址和端口
        Socket socket = new Socket("localhost",8888);
        //2.获取输出流,向服务器端发送信息
         OutputStream os = socket.getOutputStream();//字节输出流
         PrintWriter pw = new PrintWriter(os);//将输出流包装为打印流
         pw.write("用户名:admin;密码:453");
         pw.flush();//刷新缓存,向服务器端输出
         socket.shutdownOutput();

然后是UDP的客户端的代码

    //1.定义服务器的地址、端口号、数据
    InetAddress address = InetAddress.getByName("localhost");
    int port=8000;
    byte[] data = "用户名:admin;密码:123".getBytes();
    //2.创建数据报,包含发送的数据信息
    DatagramPacket packet=new DatagramPacket(data,data.length,address,port);
    //3.创建DatagramSocket对象
    DatagramSocket socket =new DatagramSocket();
    //4.向服务器端发送数据报
    socket.send(packet);

这里的客户端向本地服务器发送一些数据。令我无法理解的是为什么TCP如此复杂?
获取输出流,包装打印流,还要刷新一次缓存。相比之下UDP却又那么简单。
这是为什么?

我觉得可能是协议问题,看来最近得补补基础了。

阅读 6.8k
5 个回答

因为TCP是基于流,而UDP是基于报文啊。

TCP建立数据交互需要经过三次握手,这样就能包装交互的数据是可靠的安全的。而UDP建立的数据交互却是不需要和TCP那样要在客户端和服务器端之间简历数据交互,而是服务器直接把数据分成很多很多小的数据包,丢给客户端,这样的话,数据是不可靠不安全的,但是数据发送的快。而使用UDP传输的数据比如视频音频数据,这些数据大部分是不需要太高的安全性和可靠性,却需要速度,所以一般就会用UDP传输。

UDP的简洁是牺牲了准确以换取高效

一句话解释,TCP是要保证数据的正确性,而UDP是不保证数据的正确到达的,包丢了就丢了,适用于突发性场景,不适合于要求数据准确性的场景

并不是TCP一定要包装成打印流再发送,只是因为打印流可以直接操作字符,显得更方便
如下:
我使用字节流进行TCP传输,先启动Server,再启动Client


package thirteen;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;

public class test1_Cilent {

    private Socket socket;

    public test1_Cilent() {
        try {
            socket = new Socket("127.0.0.1", 8899);
        } catch (IOException e) {
            System.out.println("Client端连接出错");
        }
    }

    public void send() {
        try {
            BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(System.in));
            OutputStream outputStream = socket.getOutputStream();
            while (true) {
                String msg = bufferedReader.readLine();//读取键盘输入
                outputStream.write(msg.getBytes());
                outputStream.flush();
                System.out.println("Client端发送:" + msg);
                if (msg.equals("bye")) {//键盘输入终止
                    bufferedReader.close();
                    outputStream.close();
                    socket.close();
                    break;
                }
            }
        } catch (IOException e1) {
            System.out.println("Client端IO异常");
            return;
        }
    }

    public static void main(String args[]) {
        test1_Cilent cilent = new test1_Cilent();
        cilent.send();
    }

}

服务器类:

package thirteen;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class test1_Server {

    private ServerSocket serverSocket;
    private Socket socket;// 连接成功后返回的socket

    public test1_Server() {
        try {
            serverSocket = new ServerSocket(8899);
            socket = serverSocket.accept();
        } catch (IOException e) {
            System.out.println("Server端ServerScoket创建失败");
        }
    }

    public void receive() {
        try {
            String msg = null;
            while (true) {
                if (!socket.isClosed() && socket.isConnected()) {
                    byte[] bytes = new byte[1024];
                    InputStream inputStream = socket.getInputStream();//进行字节读取
                    int length = 0;
                    while((length=inputStream.read(bytes))!=-1){
                        msg = new String(bytes,0,length);
                        System.out.println("Server收到:" + msg);
                        if (msg.equals("bye")) {
                            socket.close();
                            serverSocket.close();
                            break;
                        }
                    }
                }
            }
        } catch (IOException e) {
            System.out.println("Server端读取IO出错");
        }
    }

    public static void main(String args[]) throws IOException {
        test1_Server server = new test1_Server();
        server.receive();
    }

}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题