当前位置: 首页 > 面试题库 >

如何在服务器套接字JAVA中读取所有Inputstream

何烨华
2023-03-14
问题内容

我在我的项目之一中使用Java.net。我写了一个从客户端获取inputStream的App Server。但是有时我的(缓冲的)InputStream无法获得客户端发送到我的服务器的所有OutputStream。我该如何写一个等待或类似的东西,让我的InputStream获得客户端的所有OutputStream?

(我的InputStream不是字符串

private Socket clientSocket;
private ServerSocket server;
private BufferedOutputStream outputS;
private BufferedInputStream inputS;
private InputStream inBS;
private OutputStream outBS;

server = new ServerSocket(30501, 100);
clientSocket = server.accept();

public void getStreamFromClient()  {
    try {
        outBS = clientSocket.getOutputStream();
        outputS = new BufferedOutputStream( outBS);
        outputS.flush();

        inBS = clientSocket.getInputStream();
        inputS = new BufferedInputStream( inBS );

    } catch (Exception e) {
        e.printStackTrace();
    }
}

谢谢。


问题答案:

例如,你从服务器发送了100字节的事实并不意味着你在第一次读取时将在客户端中读取100字节。从服务器发送的字节可能在几个TCP段中到达客户端。

你需要实现一个循环,在该循环中你将阅读直到收到整个消息为止。让我提供一个示例,以DataInputStream代替BufferedinputStream。举一个简单的例子。

假设你事先知道服务器要发送100字节的数据。

在客户端中,你需要编写:

byte[] messageByte = new byte[1000];
boolean end = false;
String dataString = "";

try 
{
    DataInputStream in = new DataInputStream(clientSocket.getInputStream());

    while(!end)
    {
        int bytesRead = in.read(messageByte);
        dataString += new String(messageByte, 0, bytesRead);
        if (dataString.length == 100)
        {
            end = true;
        }
    }
    System.out.println("MESSAGE: " + dataString);
}
catch (Exception e)
{
    e.printStackTrace();
}

现在,通常一个节点(这里的服务器)发送的数据大小通常是未知的。然后,你需要定义自己的小型协议,用于与TCP进行通信的服务器和客户端(或任何两个节点)之间的通信。

最常见和最简单的方法是定义TLV:类型,长度,值。因此,你定义了从服务器发送到客户端的每条消息都附带:

  • 1个字节,指示类型(例如,它也可以是2或任何数字)。
  • 1字节(或任何长度)的消息长度
  • N个字节的值(N表示长度)。
    因此,你知道你必须至少接收2个字节,而第二个字节则知道需要读取多少个后续字节。

这只是可能协议的建议。你也可以摆脱“类型”。

因此,它将类似于:

byte[] messageByte = new byte[1000];
boolean end = false;
String dataString = "";

try 
{
    DataInputStream in = new DataInputStream(clientSocket.getInputStream());
    int bytesRead = 0;

    messageByte[0] = in.readByte();
    messageByte[1] = in.readByte();

    int bytesToRead = messageByte[1];

    while(!end)
    {
        bytesRead = in.read(messageByte);
        dataString += new String(messageByte, 0, bytesRead);
        if (dataString.length == bytesToRead )
        {
            end = true;
        }
    }
    System.out.println("MESSAGE: " + dataString);
}
catch (Exception e)
{
    e.printStackTrace();
}

以下代码可以编译并看起来更好。假定提供长度的前两个字节以网络格式(大字节序)以二进制格式到达。对于邮件的其余部分,不关注不同的编码类型。

import java.nio.ByteBuffer;
import java.io.DataInputStream;
import java.net.ServerSocket;
import java.net.Socket;

class Test
{
    public static void main(String[] args)
    {
        byte[] messageByte = new byte[1000];
        boolean end = false;
        String dataString = "";

        try 
        {
            Socket clientSocket;
            ServerSocket server;

            server = new ServerSocket(30501, 100);
            clientSocket = server.accept();

            DataInputStream in = new DataInputStream(clientSocket.getInputStream());
            int bytesRead = 0;

            messageByte[0] = in.readByte();
            messageByte[1] = in.readByte();
            ByteBuffer byteBuffer = ByteBuffer.wrap(messageByte, 0, 2);

            int bytesToRead = byteBuffer.getShort();
            System.out.println("About to read " + bytesToRead + " octets");

            //The following code shows in detail how to read from a TCP socket

            while(!end)
            {
                bytesRead = in.read(messageByte);
                dataString += new String(messageByte, 0, bytesRead);
                if (dataString.length() == bytesToRead )
                {
                    end = true;
                }
            }

            //All the code in the loop can be replaced by these two lines
            //in.readFully(messageByte, 0, bytesToRead);
            //dataString = new String(messageByte, 0, bytesToRead);

            System.out.println("MESSAGE: " + dataString);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}


 类似资料:
  • 我在我的一个项目中使用Java.net。我写了一个从客户端获取输入流的应用服务器。但是有时候我的(缓冲的)输入流不能得到客户端发送到我的服务器的所有输出流。我怎么能写一个等待或类似的东西,我的输入流得到客户端的所有输出流? (我的输入流不是字符串) 谢谢。

  • 我有两个通过字符串与套接字通信的Java项目。一个是客户端,另一个是服务器。服务器通过“ServerSocket”接受连接,并使用新创建的“套接字”创建新的“会话”(线程)。 同时,客户端只有一个“套接字”,一旦连接了这个套接字,客户端就会创建一个“ClientSession”(线程,非常类似于“session”)。 我想要的是服务器通过“username”字符串询问客户机他的用户名,客户机用他的

  • 线程“main”java.net.ConnectException:连接超时:在java.net.dualStackplainsockeTimpl.Connect0(本机方法)在java.net.dualStackplainsockeTimpl.socketConnect(DualStackplainsockeTimpl.java:69)在java.net.abstractplainsockeTi

  • 我有java服务器和只有一个客户端的时间。 客户端连接并发送卡ID(在服务器端阻止读取是合适的,因为当时只有一个客户端)

  • 我正在尝试使用MQTT-Rime网关构建MQTT-SN。我成功地用串行套接字将传感器数据发送到网关,但我的网关也必须将一些数据发送到微尘。我的问题是,我不知道如何从远程的套接字读取数据。有人能帮我吗?

  • 所以我有一个PHP套接字服务器和Java套接字客户端<也许这是个愚蠢的问题。。。但我没有找到答案 在客户机中,我需要从输入流中读取传入的字节,并将它们放入字节数组中 我试图这样做: [客户端(Java)] [服务器(PHP)] 但当它读取所有字节时,在。read()不会返回-1,因此循环不会停止。有一次它返回13(长度),然后-无。有什么想法吗? 解决了 [客户端(Java)] [服务器(PHP)