等待客户端消息以读取的套接字服务器

7
我有一个Java套接字服务器,如下所示:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class MiddleSocket {
    private ServerSocket middleman;
    private int port = 1027;
    private Socket client;


    protected void createSocketServer()
    {
        try
        {
            middleman = new ServerSocket(port);
            client = middleman.accept();
            middleman.close();
            PrintWriter out = new PrintWriter(client.getOutputStream(),true);
            BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
            BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
            while(true)
            {
                System.out.println("echo: " + in.readLine());
                out.println("test");
            }
        }
        catch(IOException e)
        {
            System.out.println(e);
        }
    }

}

它在从客户端读取内容等方面的工作是正确的。然而,我希望套接字服务器仅在有来自客户端的消息时尝试读取,因为在循环中即使未收到客户端的消息,它也会继续读取,这会输出一堆
echo: null
请问除了wait()之外是否有其他机制可以让while循环知道仅需坐等并在收到客户端发来的消息后触发以读取该消息。一旦读取该消息并发送回复,则会闲置等待接收下一个消息吗?
3个回答

5
您可以简单地按照以下方式进行操作:
String line;
while ((line = in.readLine()) != null) {
   \\Do stuff
}

这应该具有预期的行为。

编辑:

这是在评论中使用您的代码谈论的完整示例:

package javaapplication12;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketExample {
    private ServerSocket middleman;
    private int port = 8080;
    private Socket client;


    protected void createSocketServer()
    {
        try
        {
            while (true){
                middleman = new ServerSocket(port);
                client = middleman.accept();
                middleman.close();
                PrintWriter out = new PrintWriter(client.getOutputStream(),true);
                BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
                BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
                String line;
                while((line = in.readLine()) != null)
                {
                    System.out.println("echo: " + line);
                    out.println("test");
                }
            }
        }
        catch(IOException e)
        {
            System.out.println(e);
        }
    }

    public static void main(String[] args){
        SocketExample test = new SocketExample();
        test.createSocketServer();
    }
}

然后,您应该在.accept命令上进行循环,该命令应处理来自连接客户端的任何输入,然后关闭连接并等待新连接。我将使用示例修改我的答案。 - WillBD
那么如果我想同时建立n个连接会发生什么?它会缓存其他消息并在上一个客户端接收到最后一条消息后发送吗? - jgr208
对于n个连接,您将需要n个线程,这将需要一个更复杂的程序版本。目前使用单线程套接字服务器,在处理一个连接的信息时,任何后续连接都将被服务器拒绝。 - WillBD
1
基本上!while(true)循环内的所有内容(而不是循环本身)都将成为线程的“内容”,您将拥有另一个类,其中包含具有.accept()方法并生成用于处理连接的线程的'while(true)'循环,然后立即返回以侦听新连接。请查看此链接:http://baptiste-wicht.com/posts/2010/09/java-concurrency-part-7-executors-and-thread-pools.html - WillBD
@BoJackHorseman 没有特别的原因,可能只是复制/粘贴错误,我会删除最后一个。 - WillBD
显示剩余5条评论

2
你可以使用InputStream.read()或InputStream.read(byte[]),两者都会阻塞。
这里有一个示例: 点击链接查看

1
我希望套接字服务器只在客户端有消息时尝试读取,因为在循环中,即使没有从客户端接收到消息,它仍会继续读取,这会输出一堆内容。
echo: null

这是因为你忽略了流的结尾,这就是 null 的含义。它并不意味着客户端没有任何消息,而是对等方已关闭连接。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接