首页 \ 问答 \ Java Socket Server不读行(Java Socket Server not reading Line)

Java Socket Server不读行(Java Socket Server not reading Line)

我有以下服务器:

public final class Server implements Runnable {
    private ServerSocket serverSocket;
    private Socket socket;
    private BufferedReader in;
    private PrintWriter out;

    Server() {
        Thread thread = new Thread(this);
        thread.start();
    }

    @Override
    public void run() {
        boolean running = true;
        try {
            serverSocket = new ServerSocket(5000);
            socket = serverSocket.accept();
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            while (running) {
                String data = in.readLine();
                System.out.println(data);
                if (data.equals("quit")) {
                    running = false;
                }
            }
        } catch (IOException e) {
            System.err.println(e);
        }
    }
}

并关注客户:

public class Client {
    private Socket socket;
    private PrintWriter out;

    public Client() {
        socket = null;

        try {
            socket = new Socket("127.0.0.1", 5000);
            out = new PrintWriter(socket.getOutputStream());
        } catch (final UnknownHostException e) {
            System.err.println("Address unknown "
                               + e.getMessage());
        } catch (final IOException e) {
            System.err.println("Error connecting to the Server "
                               + e.getMessage());
        }
    }

    public void sendMessage(String msg) {
        out.println(msg);
    }
}

我能够建立初始连接,但只要执行sendMessage()方法,服务器就不会打印任何内容。 你知道为什么我收不到消息吗?


I have following Server:

public final class Server implements Runnable {
    private ServerSocket serverSocket;
    private Socket socket;
    private BufferedReader in;
    private PrintWriter out;

    Server() {
        Thread thread = new Thread(this);
        thread.start();
    }

    @Override
    public void run() {
        boolean running = true;
        try {
            serverSocket = new ServerSocket(5000);
            socket = serverSocket.accept();
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            while (running) {
                String data = in.readLine();
                System.out.println(data);
                if (data.equals("quit")) {
                    running = false;
                }
            }
        } catch (IOException e) {
            System.err.println(e);
        }
    }
}

and following Client:

public class Client {
    private Socket socket;
    private PrintWriter out;

    public Client() {
        socket = null;

        try {
            socket = new Socket("127.0.0.1", 5000);
            out = new PrintWriter(socket.getOutputStream());
        } catch (final UnknownHostException e) {
            System.err.println("Address unknown "
                               + e.getMessage());
        } catch (final IOException e) {
            System.err.println("Error connecting to the Server "
                               + e.getMessage());
        }
    }

    public void sendMessage(String msg) {
        out.println(msg);
    }
}

I am able to establish an initial connection, but as soon as I execute the sendMessage() Method, the server doesn't print out anything. Do you know why I cannot receive a message?


原文:https://stackoverflow.com/questions/48589851
更新时间:2023-05-23 19:05

最满意答案

第一个例子:

const char * className()
{
  return "MyClass";
}

很好。 "MyClass"char const[8]类型的文字,它的生命周期在调用代码之前开始,在代码完成后结束,所以没有问题。

但是,第二个例子不起作用。

const RWCString& className()
{
  return "MyClass";
}

它要求在函数内构造RWCString类型的对象,以便能够返回对它的引用。 但是,作为局部变量或临时函数构建的内容不能通过引用返回,因此您将获得未定义的行为(如果它编译)。

你可以非常简单地把它变成一个“好”的功能:

const RWCString& className()
{
  static RWCString const N = "MyClass";
  return N;
}

这里我创建了一个本地静态对象N ,它将在第一次调用函数时构造。 因为它是static它的生命周期延伸到调用之后所以可以返回对它的引用。

编辑 :正如史蒂夫指出的那样,临时更适合这里的局部变量。


The first example:

const char * className()
{
  return "MyClass";
}

is fine. "MyClass" is a literal of type char const[8] which lifetime begins before your code is invoked and ends after your code is done, so no issue.

The second example, however, will not work.

const RWCString& className()
{
  return "MyClass";
}

It requires and object of type RWCString to be constructed within the function in order to be able to return a reference to it. However what is built as a local variable or temporary within a function cannot be returned by reference, so you get undefined behavior (if it compiles).

You can very simply turn it into a "good" function though:

const RWCString& className()
{
  static RWCString const N = "MyClass";
  return N;
}

Here I create a local static object N which will be constructed the first time the function is called. Because it is static its lifetime extends past the call so it is fine to return a reference to it.

EDIT: as Steve pointed out, temporary is more appropriate that local variable here.

相关问答

更多
  • 任何修改C字符串文字的尝试都有未定义的行为 。 编译器可以安排将字符串文字存储在只读存储器中(受操作系统保护,除非您在嵌入式系统上,否则不是字面上的ROM)。 但是这种语言并不需要这个; 作为一名程序员来做正确的决定取决于你。 一个足够聪明的编译器可能会警告你,你应该已经声明了这个指针: const char * p = "wikimedia"; 尽管没有const的声明在C中是合法的(为了不破坏旧代码)。 但是有或没有编译器警告, const是一个非常好的主意。 (在C ++中,规则是不同的;与C字符串 ...
  • 这里有一个根本的错误。 Valgrind不是某种静态分析工具,它可以理解C ++语法的语义,因此知道何时调用C ++标准指定的未定义行为 。 Valgrind是一种工具,当你在内存中进行操作时,它会提醒你,这是你的程序的未定义行为的结果。 例如,只要你访问未分配或释放的内存,它就会检测到它,它会检测你什么时候用未初始化(或部分单元化)的值/缓冲区等进行系统调用。 采取医学比喻,Valgrind检测未定义行为的症状 。 没有症状并不意味着没有未定义的行为 。 此外,因为Valgrind只检查运行的代码,所以它 ...
  • 它定义明确; 你正在创建一个数组,传递一个有效的指针到构造函数(它接受一个指针,尽管看起来好像它需要一个数组),存储该指针,然后通过它访问一个有效的数组元素。 唯一的问题是内存泄漏 - 你永远不会删除数组。 更新现在你已经添加了一个析构函数来删除数组,这个类非常危险 - 如果你复制它,那么两个副本都会尝试删除相同的数组。 这将导致未定义的行为。 根据“三条规则”,您需要阻止复制或正确实施。 如果指针不是使用new[]创建的数组,您还将获得未定义的行为。 一旦您学会了如何手动管理资源,以及获得所有细节的难度, ...
  • 当人们懒惰地将链接调用到rvalues而不是将结果存储在局部变量中时,这是一个非常常见的错误。 vector::iterator it = processSimulation(Q).begin(); 在上面,你的processSimulation(Q)调用返回vector 。 然后你获得一个迭代器到vector的开始处并存储它。 既然所得到的向量不在范围内,它就会被销毁。 这留下了一个悬而未决的迭代器。 现在你开始使用它。 请记住,该迭代器包含有效的信息,但它指向一个不再存 ...
  • 第一个例子: const char * className() { return "MyClass"; } 很好。 "MyClass"是char const[8]类型的文字,它的生命周期在调用代码之前开始,在代码完成后结束,所以没有问题。 但是,第二个例子不起作用。 const RWCString& className() { return "MyClass"; } 它要求在函数内构造RWCString类型的对象,以便能够返回对它的引用。 但是,作为局部变量或临时函数构建的内容不能通过引用返回, ...
  • 从6.15的python文档 Python从左到右评估表达式。 请注意,在评估分配时,右侧在左侧之前进行评估。 在以下行中,表达式将按其后缀的算术顺序进行计算: expr1, expr2, expr3, expr4 (expr1, expr2, expr3, expr4) {expr1: expr2, expr3: expr4} expr1 + expr2 * (expr3 - expr4) <----- This is of importance to us. expr1(expr2, expr3, ...
  • 它没有定义。 重申N1256,C99草案,6.5 / 2(强调我的): 在前一个和下一个序列点之间,一个对象应该通过评估一个表达式最多修改其存储值一次 。 72)此外,先验值只能读取以确定要存储的值。 73) It's undefined. Reffering to N1256, C99 draft, subclause 6.5/2 (emphasis mine): Between the previous and next sequence point an object shall have its s ...
  • 从C标准: 符合要求的托管实现应接受任何严格符合的程序......符合要求的实现可能具有扩展(包括附加库函数),前提是它们不会改变任何严格符合程序的行为。 换句话说,实现可以自由地保证特定行为,否则将是未定义的行为。 它不能以改变定义行为的方式来做到这一点。 From the C standard: A conforming hosted implementation shall accept any strictly conforming program... A conforming implement ...
  • “移位状态” - 实际上限于多字节文本流(和EOL处理\r\n vs \n ), 这个问题实际上仅限于文本流。 但这不是唯一的问题。 从你引用的文章中我强调: 某些平台将文件存储为固定大小的记录。 如果文件短于记录大小,则填充块的其余部分。 当你寻求“结束”时, 为了效率,它只是直接跳到最后一个块的末尾...可能在数据的实际结束之后很久,在一堆填充之后。 只要没有引发EOF标志fseek(p_file, 0, SEEK_END)后跟ftell(...)只能提供有效的答案。 阅读所引用的“解决方案(真正的大文 ...
  • 正如list()的文档还指出: 在PHP 5中,list()分配从最右边的参数开始的值。 在PHP 7中,list()以最左边的参数开头。 换句话说:这一行可能在PHP 5中按预期工作,因为双方出现的变量$diff是要分配的最后一个变量。 但是,在PHP 7中, $diff变量首先被赋值,所以$diff已经在$current和$concurrent的赋值完成时发生了变化。 总的来说,我认为关于未定义行为的提示涉及这样一个事实,即如果变量出现在=符号的两侧,则不能依赖某些赋值来产生预期结果。 该问题的解决方法 ...

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。