【发布时间】: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