В потоке 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();
}
}
}
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Почему невозможно найти log4j2 файл конфигурации хотя файл добавленПути файла менял на различные, все равно не находит
Как будет правильнее (и займёт меньше времени при выполнении), если на каждой итерации цикла создаётся новая строка?
В Android-приложении у меня реализован функционал по динамическому добавлению textView в linearLayout, и увеличению высоты этого Layout: