В потоке run() строка: clientSocket.getOutputStream().write(str.getBytes());
не хочет отправлять клиенту сообщение. Сам сервер получает их от клиента, но, как я понимаю, в getOutputStream() ничего не передается. Вопрос почему?
Сервер
public class ServerMain extends Thread {
int num;
public Thread run;
Socket clientSocket;
public List<ServerMain> clients2 = new ArrayList<>();
int port;
public ServerMain server;
public static void main(String[] args) {
ServerSocket serverSocket = null;
int i = 0;
try {
serverSocket = new ServerSocket(88);
System.out.println("Server started on port " + 88);
} catch (IOException e) {
e.printStackTrace();
}
while (true) {
try {
Socket clientSocket = serverSocket.accept();
new ServerMain(i++, clientSocket);
System.err.println("Client accepted " + i);
} catch (IOException x) {
x.printStackTrace();
}
}
}
public ServerMain(int num, Socket clientSocket) {
this.num = num;
this.clientSocket = clientSocket;
run();
}
public void run() {
run = new Thread(() -> {
try {
InputStream is = clientSocket.getInputStream();
String str;
while ((str = reader.readLine()) != null) {
System.out.println("Сообщение от клиента: " + str);
System.out.flush();
//добавляем клиента в коллекцию
// clients2.add(new ServerMain(num, clientSocket));
System.out.println(str);
clientSocket.getOutputStream().write(str.getBytes());
}
} catch (Exception e) {
System.out.println("Соединение прервалось с клиентом ");
}
}, "run");
run.start();
}
}
Клиент (представлен только метод, читающий сокет)
public void send(String bytes) {
send = new Thread(new Runnable() {
@Override
public void run() {
OutputStream out = null;
try {
out = socket.getOutputStream();
} catch (IOException e) {
System.out.println("Невозможно получить поток вывода!");
System.exit(-1);
}
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out));
try {
writer.write(bytes + "\n");
writer.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
read();
}
});
send.start();
}
Вот моё решение, возможно вам поможет, сравните с вашим кодом.
В данной программе сервер отправляет всем ранее подключенным клиентам сообщение о подключении нового клиента, все соединения с клиентом хранятся в коллекции.
Запускаете сервер и несколько раз клиент, и при запуске клиента будете видеть соответствующие сообщения у других клиентов и на сервере.
Пояснения:
.accept(); надо запускать в отдельном потоке, чтобы не останавливать основной поток.Надеюсь, я вам помог...
Сервер:
MainServer.java
public class MainServer {
public static void main(String[] args) {
System.out.println("server");
Server server = new Server();
server.startServer();
}
}
Server.java
public class Server extends Thread{
public static List<ClientConnection> connects = new ArrayList<>();
private final int port = 4444;
private ServerSocket serverSoket;
public Server() {
try {
serverSoket = new ServerSocket(port);
} catch (IOException ex) {
ex.printStackTrace();
}
}
public void run() {
while (true) {
try {
ClientConnection clientConnection = new ClientConnection(serverSoket.accept());
sendMessageAll("added: " + clientConnection.toString());
Server.connects.add(clientConnection);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
public void startServer() {
start();
}
public void stopServer() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void sendMessageAll(String msg) {
for(ClientConnection client : connects) {
client.send(msg);
}
}
}
ClientConnection.java
public class ClientConnection extends Thread{
private Socket soket;
private ObjectInputStream objectInputStream;
private ObjectOutputStream objectOutputStream;
public ClientConnection(Socket soket) throws IOException {
this.soket = soket;
objectInputStream = new ObjectInputStream(this.soket.getInputStream());
objectOutputStream = new ObjectOutputStream(this.soket.getOutputStream());
System.out.println(this.soket.toString());
start();
}
public void run() {
try {
while (true) {
System.out.print("Client: ");
String clientMessage = (String) objectInputStream.readObject();
System.out.println(clientMessage);
}
} catch (IOException | ClassNotFoundException ex) {
ex.printStackTrace();
}
}
public void send(String message) {
try {
System.out.println("Send to: " + this.soket.toString());
System.out.println(message);
objectOutputStream.writeObject(message);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Клиент:
MainClient.java
public class MainClient {
public static void main(String[] args) {
System.out.println("client");
Client client = new Client(4444);
client.Connection();
}
}
Client.java
public class Client {
private Socket socket;
private ObjectInputStream objectInputStream;
private ObjectOutputStream objectOutputStream;
private InetAddress addr;
private int port;
public Client(int port) {
try {
addr = InetAddress.getByName("localhost");
this.port = port;
} catch (UnknownHostException ex) {
ex.printStackTrace();
}
}
public void Connection() {
try {
socket = new Socket(addr, port);
objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
objectInputStream = new ObjectInputStream(socket.getInputStream());
objectOutputStream.writeObject("Hello, " + this.toString());
while (true) {
String serverMessage = (String) objectInputStream.readObject();
System.out.println(serverMessage);
objectOutputStream.writeObject("OK : " + socket.toString());
}
} catch (IOException | ClassNotFoundException ex) {
ex.printStackTrace();
}
}
}
Как развивать веб-проекты в 2026 году: технологии, контент E-E-A-T и факторы доверия
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники