Java Networking:在Socket中解释InputStream和OutputStream [英] Java Networking: Explain InputStream and OutputStream in Socket

查看:184
本文介绍了Java Networking:在Socket中解释InputStream和OutputStream的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 ServerSocket 创建了一个服务器。之后,我使用 Socket 创建了客户端,并连接到此服务器。

I have created a server by using ServerSocket. After that, I have created Client using Socket, and connect to this server.

之后,我做一些东西使用InputStream和OutputStream取自Socket Object。但是,我真的不太了解inputStream和outputStream。这是我的简单代码:

After that, I do "some stuff" with InputStream and OutputStream is taken from Socket Object. But, I don't really understand inputStream and outputStream so much. Here is my simple code :

private Socket sock = null;
private InputStream sockInput = null;
private OutputStream sockOutput = null;

...
            String msg = "Hello World";
            byte[] buffer = null;

            try {
                sockOutput.write(msg.getBytes(), 0, test.length());
                sockOutput.write("Hello StackOverFlow".getBytes(), 0, test.length());
                buffer = new byte[test.length()];
                sockInput.read(buffer, 0, test.length());
                System.out.println(new String(buffer));
                sockInput.read(buffer, 0, test.length());
                System.out.println(new String(buffer));
            } catch (IOException e1) {
                e1.printStackTrace();
                }

结果将是:Hello World和Hello StackOverFlow。

The result will be : "Hello World" and "Hello StackOverFlow".

这是服务器端代码:

private int serverPort = 0;
    private ServerSocket serverSock = null;

    public VerySimpleServer(int serverPort) {
        this.serverPort = serverPort;

        try {
            serverSock = new ServerSocket(this.serverPort);
        }
        catch (IOException e){
            e.printStackTrace(System.err);
        }
    }

    // All this method does is wait for some bytes from the
    // connection, read them, then write them back again, until the
    // socket is closed from the other side.
    public void handleConnection(InputStream sockInput, OutputStream sockOutput) {
        while(true) {
            byte[] buf=new byte[1024];
            int bytes_read = 0;
            try {
                // This call to read() will wait forever, until the
                // program on the other side either sends some data,
                // or closes the socket.
                bytes_read = sockInput.read(buf, 0, buf.length);

                // If the socket is closed, sockInput.read() will return -1.
                if(bytes_read < 0) {
                    System.err.println("Server: Tried to read from socket, read() returned < 0,  Closing socket.");
                    return;
                }
                System.err.println("Server: Received "+bytes_read
                                   +" bytes, sending them back to client, data="
                                   +(new String(buf, 0, bytes_read)));
                sockOutput.write(buf, 0, bytes_read);
                // This call to flush() is optional - we're saying go
                // ahead and send the data now instead of buffering
                // it.
                sockOutput.flush();
            }
            catch (Exception e){
                System.err.println("Exception reading from/writing to socket, e="+e);
                e.printStackTrace(System.err);
                return;
            }
        }

    }

    public void waitForConnections() {
        Socket sock = null;
        InputStream sockInput = null;
        OutputStream sockOutput = null;
        while (true) {
            try {
                // This method call, accept(), blocks and waits
                // (forever if necessary) until some other program
                // opens a socket connection to our server.  When some
                // other program opens a connection to our server,
                // accept() creates a new socket to represent that
                // connection and returns.
                sock = serverSock.accept();
                System.err.println("Server : Have accepted new socket.");

                // From this point on, no new socket connections can
                // be made to our server until we call accept() again.

                sockInput = sock.getInputStream();
                sockOutput = sock.getOutputStream();
            }
            catch (IOException e){
                e.printStackTrace(System.err);
            }

            // Do something with the socket - read bytes from the
            // socket and write them back to the socket until the
            // other side closes the connection.
            handleConnection(sockInput, sockOutput);

            // Now we close the socket.
            try {
                System.err.println("Closing socket.");
                sock.close();
            }
            catch (Exception e){
                System.err.println("Exception while closing socket.");
                e.printStackTrace(System.err);
            }

            System.err.println("Finished with socket, waiting for next connection.");
        }
    }

    public static void main(String argv[]) {
        int port = 54321;
        VerySimpleServer server = new VerySimpleServer(port);
        server.waitForConnections();
    }

我的问题是:


  1. 当我使用 sockOutput.write 时,我可以通过 sockInput.read返回这些消息。所以,这些消息已被保存,对吧?如果这是真的,它是否保存在我创建的服务器上,或者只保存在其他东西中,例如套接字对象

  1. When I use sockOutput.write and I can get back those message back by sockInput.read. So, those message has been saved, right? If this true, does it saved on Server I have created or just saved in some other thing such as Socket Object.

如果我已写入套接字字符串A1,A2,......那么我将分别收到A1,A2,...一个字符串,对吗?

If I have written to socket String A1, A2,... An so I will receive A1, A2, ... An String respectively, right?


推荐答案

套接字是一种抽象,可用于与网络中的某些内容进行通信。请参见下图...

A socket is an abstraction that you use to talk to something across the network. See diagram below...

在Java中,要通过套接字发送数据,您将获得 OutputStream (1 )从它,并写入 OutputStream (你输出一些数据)。

In Java, to send data via the socket, you get an OutputStream (1) from it, and write to the OutputStream (you output some data).

从套接字读取数据,你得到它的 InputStream ,并从第二个流中读取输入。

To read data from the socket, you get its InputStream, and read input from this second stream.

你可以把这些流想象成一个一对单向管道连接到墙上的插座。在墙的另一边发生的事情不是你的问题!

You can think of the streams as a pair of one-way pipes connected to a socket on the wall. What happens on the other side of the wall is not your problem!

在你的情况下,服务器有另一个套接字(连接的另一端)和另一对流。它使用 InputStream (2)从网络中读取,并使用 OutputStream (3)来编写相同的数据通过网络返回到您的客户端,它通过 InputStream (4)再次读取它完成往返。

In your case, the server has another socket (the other end of the connection) and another pair of streams. It uses its InputStream (2) to read from the network, and its OutputStream (3) to write the same data back across the network to your client, which reads it again via its InputStream (4) completing the round trip.

      Client                                                     Server

1. OutputStream -->\                                     /--> 2. InputStream -->
                    Socket <--> network <--> ServerSocket                       |
4. InputStream  <--/                                     \<--3. OutputStream <--

更新:以回复评论:

请注意,流和套接字只发送原始字节;他们在这个抽象层面上没有信息的概念。因此,如果您发送X个字节和另外X个字节,然后读取X个字节并读取另外X个字节,那么您的系统就像有两个消息一样,因为这就是你如何划分字节。

Note that the streams and sockets just send raw bytes; they have no notion of a "message" at this level of abstraction. So if you send X bytes and another X bytes, then read X bytes and read another X bytes, then your system behaves as if there are two messages, because that's how you've divided up the bytes.

如果您发送X个字节和另外X个字节,然后读取长度为2X的回复,那么您可能能够读取单个组合的消息,但是您已经注意到,流的底层实现可以选择何时传递块的字节,因此它可能返回X字节,然后是X字节,稍后,或者一次返回2X,或者是0.5X四次......

If you send X bytes, and another X bytes, then read a reply of length 2X, then you might be able to read a single combined "message", but as you've noticed, the underlying implementation of the streams can choose when to deliver chunks of bytes, so it might return X bytes, then X bytes, later, or 2X at once, or 0.5X four times...

这篇关于Java Networking:在Socket中解释InputStream和OutputStream的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆