Я работаю с 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 вызывает метод listenToSocket() из класса SocketListener
- listenToSocket() описано выше
- SocketMessageThread обрабатывает сообщение вывода клиентского сокета в его методе run().
EDIT Вот код моего 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();
}
}}
EDIT 2 Оба клиенты взаимодействуют только с одним конкретным сообщением. Например. когда клиент запускается, он упомянул, что запуск был успешным с одним сообщением. Нет повторных сообщений, поступающих из клиентских сокетов, до тех пор, пока их не уловят серверные сокеты. Поэтому, если серверный сокет не поймает это сообщение, он исчез, и он не будет отправлен снова клиентским сокетом.
Код сервера правильный, поскольку вы начинаете новый поток для каждого нового клиента и отправляете адрес сокета для каждого клиента. Для общения с каждым клиентом вам необходимо поддерживать разные входные выходные потоки. Напр. если есть два клиента: - клиент A и клиент B. Затем сервер будет принимать запрос на подключение 1-го, тогда поток будет обрабатывать дальнейший запрос, и поток будет связываться с клиентом, поддерживая отдельный выходной поток отдельно. –
Я думаю, что сокет - это синхронный канал связи «один к одному».Если ваш первый клиент не выпускает сокет, второй никогда не сможет подключиться (сервер может также прервать связь, закрыть и снова открыть сокет для прослушивания других клиентов). –
@francescoforesti Ваш комментарий не имеет смысла. Принятые сокеты независимы. Первому клиенту не нужно «освобождать сокет», чтобы второй клиент мог подключиться. Задержка прослушивания позаботится об этом, если ничего не сделает. В вопросе о том, что второй клиент не может подключиться, нет ничего. – EJP