【问题标题】:No response from second client socket第二个客户端套接字没有响应
【发布时间】:2015-05-27 08:02:33
【问题描述】:

我正在使用 Java 套接字。我有一个服务器套接字和两个客户端套接字。我的问题是,第一个客户端套接字将其消息提交给我的服务器套接字,而来自第二个客户端套接字的消息没有到达服务器套接字。这意味着,对于第一个客户端套接字,while 循环在成功消息后中断,第二个客户端以无限 while 循环结束。如果我在测试类中单独测试每个客户端套接字,则每个客户端套接字都会正确地将其消息提交给我的服务器套接字。通过观看 TCPView 我注意到,只要我的端口被使用,客户端套接字就不会响应。

我读到,即使使用了端口,第二个客户端套接字仍应响应其消息。在我的情况下,第二个客户端套接字应该总是在第一个之后大约一秒钟响应。但我不能让他们一个接一个地工作。

所以,这是我的方法代码,它正在等待客户端消息:

public void listenToSocket()
{
    serverSocket = null;
    thread = null;
    SocketAddress adress = new InetSocketAddress(CommunicationValues.SOCKET_PORT);
    try {
        serverSocket = new ServerSocket();
        serverSocket.setReuseAddress(true);
        serverSocket.bind(adress);

    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
        System.exit(0);
    }




    while(true){
        try
        {
            Socket clientSocket = serverSocket.accept();
            thread = new SocketMessageThread(clientSocket);
            thread.start();         

        } catch (IOException e) {
            System.out.println("MyServerSocket caught an error: \n" + e.getMessage());
            e.printStackTrace();
        }
    }

}

此方法在线程中调用。结构如下:

  • SocketListenerThread 调用 SocketListener 类中的方法 listenToSocket()
  • listenToSocket() 如上所述
  • SocketMessageThread 正在其 run() 方法中处理客户端套接字的消息输出。

编辑 这是我的 SocketMessageThread 的代码:

public class SocketMessageThread extends Thread{

private Socket clientSocket;
private static int nameCounter = 0;


public SocketMessageThread(Socket clientSocket) {
    this.clientSocket = clientSocket;
    this.setDaemon(true);
    this.setName("SocketMessageThread" + (nameCounter++));
}

public void run() {
    try (
            BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));)
    {
        while (in.ready())
        {
            String inLine = in.readLine();
            CommunicationValues.MESSAGE_MEMORIZER = inLine;
        }
        clientSocket.close();

    } catch (IOException e) {
        e.printStackTrace();
    }   
}}

编辑 2 两个客户端只与一个特定的消息进行通信。例如。当客户端启动时,它提到,启动成功并带有一条消息。在服务器套接字捕获它们之前,没有来自客户端套接字的重复消息。因此,如果服务器套接字没有捕捉到那条消息,它就消失了,客户端套接字也不会再次发送它。

【问题讨论】:

  • 您的服务器代码是正确的,因为您正在为每个新客户端启动一个新线程并为每个客户端发送套接字地址。为了与每个客户端进行通信,您需要维护不同的输入输出流。例如。如果有两个客户端:- 客户端 A 和客户端 B。然后服务器将首先接受连接请求,然后线程将处理进一步的请求,线程将通过分别维护输入输出流与客户端通信。
  • 我认为套接字是一对一的同步通信通道。如果您的第一个客户端不释放套接字,则第二个客户端将永远无法连接(服务器也可能中断通信,关闭并重新打开套接字以监听其他客户端)。
  • @francescoforesti 您的评论开始没有意义。接受的套接字是独立的。第一个客户端不必为第二个客户端“释放套接字”就可以连接。如果没有其他事情,listen backlog 会处理这个问题。关于第二个客户端无法连接的问题没有任何内容。
  • 这里没有等待客户端消息的内容。 SocketMessageThread 的构造函数是做什么的?如果它在套接字上执行任何 I/O,它不应该这样做,因为这会阻止并可能阻塞接受线程。所有 I/O 都应推迟到其run() 方法。您需要发布更多代码。
  • @PranavAgrawal 当我为每个线程创建一个新流时,我没有这样做吗?看看我添加的代码,也许你现在可以给我更多的细节。

标签: java multithreading sockets response runnable


【解决方案1】:
while (in.ready())
{
    // ...
}

ready(). 的经典误用将这一切换成:

String inLine;
while ((inLine = in.readLine()) != null)
{
    CommunicationValues.MESSAGE_MEMORIZER = inLine;
}

可能还有更多代码您没有向我们展示:否则这一切都会做的就是记住发送的最后一行。

【讨论】:

  • 我会试试的。那个 .ready() 方法一直困扰着我。但是自从我的同事编写了代码示例并告诉我,他的客户端套接字就是这样工作的,我从未更改过它。
  • 我试过了,但是没有用。按原样更改代码会导致 NullPointerException。将 MESSAGE_MEMORIZER 放入带有捕获 Null 值的 if 中,会导致无限 while 循环。两者都发生在等待第一个客户端套接字时。也许我应该提到,每个客户端只在 outstream 上写一条消息(当它通知时,程序启动成功)。使用in.ready() 正在为第一个客户端工作。顺便说一句:感谢您与我分享您的想法。
  • 如果您复制了上面的代码,则不可能NullPointerException,除非输入流为空。如果只有一行要读取,请将while 更改为if
  • 呵呵,好笑。我复制了您的代码,但我忘记在 if 子句中删除额外的 inLine = in.readLine(),在 MESSAGE_MEMORIZER 的分配之上。由于我删除了该行,代码在while 下运行良好,非常感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-23
  • 2018-05-23
  • 2015-06-05
  • 1970-01-01
  • 2015-03-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多