当前位置: 首页 > 知识库问答 >
问题:

Java:无法在套接字插入后写入套接字。readLine()

汝飞
2023-03-14

我转向你,在这件事上我一直把头撞在墙上。

我正在做一个小的socket编程,我可以看到当我把它放出来。println(“…”)while循环之前的代码行(in.readLine())它工作正常,但我需要它位于循环内部。

说清楚一点,我没有看到任何错误。我只是看不到此应用程序的客户端显示文本。它看起来好像在工作,但事实并非如此。此外,我也不控制该应用程序的客户端,它由通过TCP连接到此套接字侦听器应用程序的设备处理。是否有可能在读取数据后立即切断连接?

public class ConnectionHandlerTCP implements Runnable
{
        private final Socket clientSocket;

        ConnectionHandlerTCP(Socket socket)
        {
                clientSocket = socket;
        }

        public void run()
        {
                int uniqueId = 0;
                try (
                        BufferedReader in = new BufferedReader( new InputStreamReader(clientSocket.getInputStream()));
                        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
                ){
                        String inputLine;

                        // This Line WORKS, I see it appear on the other side of the connection.
                        Log.debug("Sending now A");
                        out.println("text to send here");

                        while ((inputLine = in.readLine()) != null)
                        {
                                // This Line DOES NOT WORK, I do not see it on the other side of the connection.
                                //Log.debug("Sending now B");
                                //out.println("text to send here");

                                // ... bunch of commented out code here
                        }

                        in.close();
                        out.close();
                        clientSocket.close();
                } catch (IOException e) {
                        Log.error("Exception caught when trying to read input.", e.getMessage());
                } catch (Exception e) {
                        Log.error("Exception caught when trying to parse data.", e.getMessage());
                }
        }
}

任何帮助都将不胜感激。如果有帮助,这里是主要的课程。

import java.net.*;
import java.io.*;

public class SocketListenerTCP 
{
    public static void main(String[] args) throws IOException {

        if (args.length != 1) {
            System.exit(1);
        }

        int portNumber = Integer.parseInt(args[0]);

        while(true)
        {
            try ( 
                ServerSocket serverSocket = new ServerSocket(portNumber);
            ) {

                Socket clientSocket = serverSocket.accept();

                new Thread(new ConnectionHandlerTCP(clientSocket)).start();

            } catch (IOException e) {
                Log.error("Exception caught", e.getMessage());
            }
        }
    }
}

我把它简化了一点,完全去掉了循环,但仍然不能正常工作。

                inputLine = in.readLine();
                Log.debug(inputLine);  

                Log.debug("Sending now");
                out.println("text to send here");

共有3个答案

诸葛雅达
2023-03-14

读取套接字连接的输入流是线程阻塞。您不能在同一个线程中同时读写。将打印机移动到另一个线程中,你应该没问题。

孙熠彤
2023-03-14

我想我终于找到了问题的症结所在。首先解释我最初的问题。我现在确信,我连接的设备在20秒左右没有读/写任何活动后会与我的服务器应用程序断开连接。所以readline()将等待20秒后返回它所拥有的一切,此时不允许写回设备。然而,如果我一次只读取一个字符(通过read()),它工作得很好,允许我读取整个消息,并在read()循环的最后一个字符读取迭代中等待最后的“-1”通过,发出有效负载结束的信号。在这段时间(读取第一个字符和等待最后一个字符)之间,我解析有效负载并向设备发送任何我想要的内容。它收到的大部分信息。

我的第二个问题是,有时输出流似乎断开了连接,不再让我发送任何消息。在最初的代码中,我让类实现了“Runnable”。这是个错误。我到处都看到使用Runnable是实现这一点的首选方法,但我注意到OutputStream在这种情况下很少工作,我转而扩展了Thread类,它几乎100%的时间都能工作。我认为一个线程过度写入另一个线程的输出流,然后下一个线程做同样的事情,然后每个线程都无法通过输出流进行通信。

在网上查看了其他一些示例之后,我假设如果我想使用Runnable,我可以使用某种方式,但必须重构应用程序中的其他一些项。在我回到那条路上之前,我得多读点书。

无论如何,它目前似乎运行平稳,现在很少失败。我仍然很想知道为什么它有时仍然失败,所以我会在时间允许的情况下继续研究。

我仍然有点困惑,有一位评论者说我不能在同一条线上读写。。。这似乎是完全错误的,只要在向设备写入之前先读一个I read()(而不是readLine()),读写似乎就可以正常工作。

齐栋
2023-03-14

里面的代码

while((inputLine=in.readLine())!=空)

很可能没有运行,因为中存在。readLine一直在等待客户端的输入。

客户端程序/套接字需要让它处于PrintWriterprintln状态,这样你的while循环就可以读取并响应它(假设这就是你想要实现的)。

 类似资料:
  • 在我的客户端/服务器应用程序中,我的客户端wiil与服务器通信有两个功能:客户端要么向服务器请求数据,要么发送数据,以便服务器保存。我对这两种方法都使用一个套接字,要使用的方法由发送的第一个字节定义。如果第一个字节是“1”,它将请求数据。如果是“2”,它将发送数据(数据字节在“2”字节之后发送)。它非常适合发送数据。但是当我请求数据时,只要我不读取客户端中的套接字流,它就可以工作。这就像如果我在发

  • 我想从Java应用程序通过套接字发送一个简单的。我的问题是,如果不在的末尾添加'\n',编写就不起作用。我必须添加这个“\n”还是有更优雅的解决方案? 这是我的代码:

  • 我正在尝试在java中使用httpPost请求(通过MultipartEntityBuilder)上传文件。但是我得到了一个软件导致的连接中止:套接字写入错误。 这是我的httpPost正文(在wireShark中) 代码端为: 和错误: 有什么想法吗?谢谢大家。

  • 我正在尝试用套接字从客户端向服务器写入一个结构。 结构是: 这两个程序(服务器、客户机)的结构是相同的,并且这两个程序的结构是相同的。 客户端程序: 结构R*r; 马洛克.. ...(用数据填充结构) write(socket_fd,(void*)r,size of(R)); 服务器程序: 结构R*r; 马洛克.. read(client_fd,(R*)r,size of(R)); 这不是将结构从

  • 问题内容: 为什么有人会喜欢阻止写而不是非阻止写?我的理解是,仅当您想确保写方法返回后,另一端获得了TCP数据包时,才希望阻止写操作,但是我什至不知道这是可能的。您将必须刷新,而刷新则必须刷新 底层操作系统的写套接字缓冲区 。那么,无阻塞套接字写是否有任何缺点?就性能而言,拥有较大的底层写套接字是否会缓冲一个不好的主意?我的理解是,底层套接字写缓冲区越小,当底层套接字缓冲区已满且isWritabl

  • 问题内容: 我正在寻找一种使用Go语言与UDP套接字进行客户端/服务器通信的好的解决方案。 我在Internet上找到的示例向我展示了如何将数据发送到服务器,但是没有讲授如何将数据发送回客户端。 为了演示,我的程序执行以下操作: 我的客户端程序在4444端口上创建一个套接字,如下所示: 我向服务器发送了字符串和本地地址,因此它可以打印字符串并发送OK消息。我为此使用gob: 我的数据结构如下所示: