Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用套接字从服务器线程中的套接字读取数据_Java_Sockets_Server - Fatal编程技术网

Java 使用套接字从服务器线程中的套接字读取数据

Java 使用套接字从服务器线程中的套接字读取数据,java,sockets,server,Java,Sockets,Server,应用程序具有客户端和服务器线程。客户端线程工作正常。 从服务器读取另一个应用程序上的客户端发送到我的应用程序的内容时出现问题 实现此服务器有两个要求 我需要使用UTF-16LE编码 我不能使用readLine,我只需要使用read byte/s 我尝试了许多例子,但似乎没有什么能正常工作 这是服务器的代码 private static final int NUM_STATUSES = 30; private static final int NUM_ERRORES =

应用程序具有客户端和服务器线程。客户端线程工作正常。 从服务器读取另一个应用程序上的客户端发送到我的应用程序的内容时出现问题

实现此服务器有两个要求

  • 我需要使用UTF-16LE编码
  • 我不能使用readLine,我只需要使用read byte/s
  • 我尝试了许多例子,但似乎没有什么能正常工作

    这是服务器的代码

    private static final int    NUM_STATUSES    = 30;
    private static final int    NUM_ERRORES     = 50;
    private ServerSocket        _serverSocket;
    private Socket              _socket;
    private Handler             _handler;
    private int                 _port;
    
    //handler of main activity
    public ServerNetworkThread()
    {
        setName("ServerNetworkThread");
    }
    
    public void setHandler(Handler h)
    {
        _handler = h;
    }
    
    @Override
    public void run()
    {
    
        _isWorking = true;
        try
        {
            _serverSocket = new ServerSocket();
            _serverSocket.setReuseAddress(true);
            _serverSocket.bind(new InetSocketAddress(_port));
    
            while (_isWorking)
            {
                _socket = _serverSocket.accept();
                _socket.setSoTimeout(Consts.CLIENT_SOCKET_TIMEOUT);
    
                readDataTest();
    
            }
    
        }
        catch (SocketTimeoutException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    
    }
    
    private void readDataTest() throws IOException
    {
        //          BufferedReader inFromClient = new BufferedReader(new InputStreamReader(_socket.getInputStream(),Charset.forName("UTF-16LE")));
        InputStream iStream = _socket.getInputStream();
        InputStreamReader in = new InputStreamReader(iStream, Charset.forName("UTF-16LE"));
        DataOutputStream outToClient = new DataOutputStream(_socket.getOutputStream());
        char[] buf = new char[iStream.available()];
        in.read(buf, 0, buf.length);
        String request = new String(buf);
    
        String responseStr = parseResponse(request);
        byte[] response = responseStr.getBytes("UTF-16LE");
        outToClient.write(response);
        outToClient.flush();
        outToClient.close();
        in.close();
        _socket.close();
        //          inFromClient.close();
    }
    
    有时,当我试图读取服务器从客户端接收到的数据时,会收到超时


    谢谢你的帮助

    我曾经处理过类似的问题。我需要使用UTF-16获取一个字符串,其中字节编码为UTF-8。所以我写了这个方法:

    //NOTE: 'charsetName' has to be a valid Name (see 'Charset'-Class in the API)
    public String encode(char[] data, String charsetName)
    {
        //Convert char[] to a String
        String charString = String.copyValueOf(data);
        String encoded = "";
    
        try 
        {
            //Since there is no constructor which lets you set char[] with encoding
            //convert your String to a byte-Array. There is a constructor which lets 
            //you set the Encoding for it.
            byte[] bytesEncoded = charString.getBytes(charsetName);
    
            //Construct a String using the encoding
            encoded = new String(bytesEncoded, charsetName);
        } 
        catch (UnsupportedEncodingException e) 
        {
            e.printStackTrace();
        }
    
        return encoded;
    }
    
    (将“UTF-16LE”设置为charsetName)


    前后转换数据看起来有点“脏”,但对我来说它工作得很好。

    最后对我有用的是:

  • 我总是分配大小为1024的缓冲区,而不使用Ata注意到的iStream.available()
  • 在多次尝试之后,我不知道如何在“EOF”之后摆脱所有的字符。我只是将接收到的字符串按EOF进行拆分,并获取字符串的第一个片段,结果很好。EOF符号结束来自客户端的请求 这就是我最终使用的代码

    private void readDataTest() throws IOException
    {
        InputStream iStream = _socket.getInputStream();
        InputStreamReader in = new InputStreamReader(iStream, Charset.forName("UTF-16LE"));
        DataOutputStream outToClient = new DataOutputStream(_socket.getOutputStream());
        char[] buf = new char[1024];
        in.read(buf, 0, buf.length);
        String request = new String(buf);
        request = request.split(Consts.EOF)[0];
    
        String responseStr = parseResponse(request);
        byte[] response = responseStr.getBytes("UTF-16LE");
        outToClient.write(response);
        outToClient.flush();
        outToClient.close();
        in.close();
        _socket.close();
    }
    

    你的答案的问题不是某个虚构的EOF角色,而是你忽略了读取计数。应该是

    int count = in.read(buf);
    if (count == -1)
        throw new EOFException();
    String request = new String(buf, 0, count);`
    

    你能发布stacktrace吗?在打印我收到的内容后,我注意到一些奇怪的事情:request=BB00060011└א└א└א└א└א└א└א└א└א└א└א└א└א└א└א└א└א└א└א└א└א结尾有许多字符不需要在那里,可能行char[]buf=new char[iStream.available()]有问题;在
    字符串请求中=新字符串(buf)您正在使用UTF-8构建一个字符串,其中字节来自UTF-16L。在构造字符串时指定字符集没有字符串构造函数可以通过编码获取char[],如何解决这个问题?一个大问题是用来创建缓冲区和请求的iStream.available()。available只告诉您有多少字节可用,它不会告诉您请求是否完成。您需要一些关于您将要接收的请求字节数或某种请求结束字符的指示。你的请求将是不完整的,否则大多数时候,你的回复也将是不完整的。不幸的是,我仍然收到一些奇怪的字符。但是谢谢你的帮助!。EOF不是数据中的一个字符。是的,你可以看到我使用的是Consts.EOF,这个字符串是“”,一个字符串表示收到的字符串的结尾,你可以在第一篇文章的第二条注释中看到。那么你的代码正在发送一些EOF字符?没有显示在任何地方。正如我所说,在打印我收到的内容后,你可以在第一篇文章的第二条评论中看到这一点,我注意到一些奇怪的事情:request=BB00060011└א└א└א└א└א└א└א└א└א└א└א└א└א└א└א└א└א└א└א└א└א结尾有许多字符不需要在那里,可能行char[]buf=new char[iStream.available()]有问题;