如何停止Java Socket客户端不断发送“空”数据?

时间:2019-02-02 14:40:28

标签: java sockets server iostream

我创建了2个带有套接字的Java程序。我希望客户端将连续数据发送到服务器。但是在消息发送到服务器后,客户端继续向服务器发送“空”值(在我关闭客户端程序中的套接字时会发生这种情况)。 这是我的代码:

public class MainServer {

    private ServerSocket serverSocket;
    private int listenPort = 8282;
    private InputStream inps;
    private Socket clientSocket;
    private BufferedReader clientInput;

    private MainServer() {
        String clientMsg = "";
        try {
            serverSocket = new ServerSocket(listenPort);
            System.out.println("Server is Listening on " + listenPort);
            clientSocket = serverSocket.accept();
            clientInput = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            while(clientSocket.isConnected()) {
                clientMsg = clientInput.readLine();
                System.out.println("Client : " + clientMsg);                
            }
        }catch(IOException ex) {
            ex.printStackTrace();
        }finally {
            try {
                clientSocket.close();
            } catch (IOException e) {}
        }
    }
    public static void main(String[] args) {
        new MainServer();
    }
}

服务器端:

clientOutput.close();

我试图用serverSock.close();关闭客户端的OutputStream,但是在发送0-4循环后,它向服务器发送了null。 为了使其停止并避免客户端发送空数据,我不应该在客户端上插入Client: 0 Client: 1 Client: 2 Client: 3 Client: 4 Client: null Client: null //And so on.. ,但是它将返回SocketException。我希望客户端在完成后发送“已关闭”消息。

摘要,服务器上的输出为:

{{1}}

我认为客户端程序中缺少一些内容吗? 谢谢您的帮助:)

3 个答案:

答案 0 :(得分:1)

正如评论所指出的,客户端没有发送null值。

isConnected()方法不会做你认为是这样,即它的的告诉你,如果该套接字当前的方式“连接”到它的同行,至少你认为应该。 isConnected()一旦套接字转换为连接状态就变为true,此后保持为true,即使套接字关闭后也是如此。有关stackoverflow的信息,请参见this discussion和其他人。

,以确定该对等体已关闭的连接是尝试从套接字读然后检查闭合的证据的结果的正确方法。请阅读您使用的方法的Javadocs,它们会告诉您各种返回值的含义。对于BufferedReader.readLine()方法,它表示:

  

返回:
  字符串,包含该行的内容,不包括   任何行终止符或null如果该流的端部具有   已达成
  抛出
  IOException - 如果发生一个I / O错误

因此需要检查空返回值来检测正常插座闭合,并且如果收到一个IOException指示某种网络的异常。

答案 1 :(得分:-1)

您MainClient()都没有问题。

clientSocket.isConnected()在MainServer(功能)总是检查客户端的状态,并从而导致无限循环,消息“客户端:4”后所以,clientInput.readLine()应该返回“空”

因此,而不是检查客户端套接字连接或不可以检查客户端套接字被关闭或不使用函数“clientSocket.isClosed()”

用下面的代码替换MainServer()中的while循环

       while(!clientSocket.isClosed()) {

                clientMsg = clientInput.readLine();
                System.out.println("Client : " + clientMsg);

                if(clientMsg.equals("Closed")){
                     clientSocket.close();
                //  serverSocket.close();
                }
            }

这将帮助您在收到来自服务器的“ Closed”消息时关闭客户端套接字,从而避免了while循环的无限执行以及null语句的打印。 代码“serverSocket.close()”帮你关闭服务器套接字,你可以在“MainServer()”,如果你需要停止端口监听使用。

答案 2 :(得分:-2)

通常,代码应类似于

private MainServer() {
  String clientMsg = "";
  try {
    serverSocket = new ServerSocket(listenPort);
    System.out.println("Server is Listening on " + listenPort);
    clientSocket = serverSocket.accept();
    clientInput = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    while ((clientMsg = clientInput.readLine()) != null) {
      if(isTerminationString(clientMsg)) { 
        break;
      }
      System.out.println("Client : " + clientMsg);
    }
  } catch (IOException ex) {
    ex.printStackTrace();
  } finally {
    try {
      clientSocket.close();
    } catch (IOException e) {
    }
  }
}

boolean isTerminationString(String msg) {
  return msg.equals("DONE!");
}

isTerminationString中,如果您检查味精是否是终止味精,则应该在客户端和服务器之间共享通信协议。我以发送为例 DONE 消息,但它可能比这更复杂。 因为关闭套接字上的close方法并不能保证其他部分的套接字也被关闭,所以使用isClosed方法可能无效,并导致您遇到相同的问题。