-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716
1

Многопользовательский TCP чат

06.12.2019, 01:32. Показов 4815. Ответов 12
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Для отправки сообщений юзаю PrintWriter, поэтому flush'ить не надо.
Вижу на сервере что юзеры подсоединяются, но сообщения не транслируются. Кто подскажет че не так делаю?
Сервак
Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import java.io.*;
import java.net.*;
import java.util.LinkedList;
 
public class TCPServer {
 
    final static int PORT = 1001;
    static LinkedList<ClientThread> clientsList = new LinkedList<>();
    private static Socket clientSocket;
    private static ServerSocket serverSocket;
    
    public static void main(String[] args) throws IOException {
        serverSocket = new ServerSocket(PORT);
        System.out.println("Start Server on "+PORT+" port");
        while(true) {
            try {
                clientSocket = serverSocket.accept();
                System.out.println("get new connection");
                ClientThread сlientThread = new ClientThread(clientSocket);
                clientsList.add(сlientThread);
            }
            catch(IOException ioe) { 
                ioe.printStackTrace();
            }
        }
    }
}
    
    class ClientThread extends Thread {
        Socket socket;
        BufferedReader in;
        PrintWriter out;
        
        ClientThread(Socket s) throws IOException { 
            socket = s; 
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));
            start();
        }
        
        public void run() {
            try {
                while(true) {
                    String clientMessage = in.readLine();
                    System.out.println("Server Says: " + clientMessage);
                    if(clientMessage.equals("stop"))
                        break;
                    for (ClientThread ct : TCPServer.clientsList) {
                        ct.out.write(clientMessage);
                    }
                    
                }
            }
        catch(Exception e) { 
            e.printStackTrace();
        }
    }
}


Клиент
Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.*;
 
public class TCPClient {
    
    static String clientName;
    static Socket clientSocket;
    static PrintWriter out;
    static BufferedReader in;
    static BufferedReader stdIn;
 
    public static void main(String[] args) throws IOException {
        
        clientSocket = new Socket("localhost", 1001);
        out = new PrintWriter(clientSocket.getOutputStream(), true);
        in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        stdIn = new BufferedReader(new InputStreamReader(System.in));
        
        getNickname();
        
        new Thread() {
            @Override
            public void run() {
                while(true) {
                    try {
                        String mesage = in.readLine();
                        if (mesage.equals("stop")) {
                            break;
                        }
                        System.out.println(mesage);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            }.start();
            
            
        while(true) {
            String userMessage;
            userMessage = stdIn.readLine();
            if (userMessage.equals("stop")) {
                out.write("stop" + "\n");
                break;
            } else {
                out.write(userMessage);
                out.flush();
            }
        }
        
        
    }
    
    
    private static void getNickname() throws IOException {
        System.out.print("Press your nick: ");
        clientName = stdIn.readLine();
    }
 
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.12.2019, 01:32
Ответы с готовыми решениями:

TCP чат на 2 и более пользователей
Нужно сделать чат на двух и более пользователей. Сервер принимает данные только от одного...

Написать чат с использованием TCP-сокетов
Здравствуйте , задали(на самостоятельное изучение) написать чат с использованием tcp...

Многопользовательский чат
Продолжая тему: https://www.cyberforum.ru/c-linux/thread739166.html . Чат подправил и все...

Многопользовательский чат
Подскажите, как в таком чате сделать так, чтобы к серверу могли подключаться несколько клиентов, и...

12
406 / 278 / 93
Регистрация: 14.03.2017
Сообщений: 777
06.12.2019, 02:46 2
Лучший ответ Сообщение было отмечено SadiQ228 как решение

Решение

1. Не указывайте такие маленькие порты. Обычно, свободные начинаются с 8000, а меньше - уже больше для системных программ.
2. PrintWriter / Writer отправляют данные когда указывается \n, иначе используйте println у PrintWriter. То же самое и для сервера сделать
3. У сервера, во время отправки сообщения - flush

Добавлено через 8 минут
Немного не прав, PrintWriter / Writer - отправляют, но по ту сторону ожидают целую строку с флагом окончания строки \n\r / \n
1
-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716
06.12.2019, 02:47  [ТС] 3
как попробую отпишусь о результатах
0
Эксперт функциональных языков программированияЭксперт Java
4485 / 2720 / 485
Регистрация: 28.04.2012
Сообщений: 8,585
06.12.2019, 14:49 4
sdasdaw, про порты ты не прав: не для системных и не до 8000, а до 1024, насколько помню. И это в любом случае не влияет на работоспособность
0
-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716
06.12.2019, 15:03  [ТС] 5
насчет портов да, там прямо написано что порты до тыщи и это не моя ошибка, у меня там сервак даже не получает сообщение от подключенного клиента хз почему пока не понимаю, подставил флаги результата нету
0
406 / 278 / 93
Регистрация: 14.03.2017
Сообщений: 777
06.12.2019, 15:28 6
Цитата Сообщение от korvin_ Посмотреть сообщение
не прав: не для системных и не до 8000, а до 1024, насколько помню.
Ок, гугл сказал, что 49152-65535 - для пользователей
А 1024-49151 - полу резервные, и тоже не стоит использовать для юзеров.

Цитата Сообщение от korvin_ Посмотреть сообщение
И это в любом случае не влияет на работоспособность
Неа, у меня на линуксе было отказано в доступе с портом который у ТСа.

Добавлено через 59 секунд
Цитата Сообщение от SadiQ228 Посмотреть сообщение
подставил флаги результата нету
А flush?
1
-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716
06.12.2019, 20:58  [ТС] 7
да какого то фига надо флушить даже PrintWriter хотя в доках написано что не надо
выкладываю MVP для всех наших))


Server:
Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import java.io.*;
import java.net.*;
import java.util.LinkedList;
 
public class TCPServer {
 
    final static int PORT = 8001;
    static LinkedList<ClientThread> clientsList = new LinkedList<>();
    private static Socket clientSocket;
    private static ServerSocket serverSocket;
    
    public static void main(String[] args) throws IOException {
        serverSocket = new ServerSocket(PORT);
        System.out.println("Start Server on "+PORT+" port");
        while(true) {
            try {
                clientSocket = serverSocket.accept();
                System.out.println("get new connection");
                ClientThread сlientThread = new ClientThread(clientSocket);
                clientsList.add(сlientThread);
            }
            catch(IOException ioe) { 
                ioe.printStackTrace();
            }
        }
    }
}
    
    class ClientThread extends Thread {
        Socket socket;
        BufferedReader in;
        PrintWriter out;
        
        ClientThread(Socket s) throws IOException { 
            socket = s; 
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));
            start();
        }
        
        public void run() {
            try {
                while(true) {
                    String clientMessage = in.readLine();
                    System.out.println("Server Says: " + clientMessage);
                    for (ClientThread ct : TCPServer.clientsList) {
                        ct.out.write(clientMessage + "\n");
                        ct.out.flush();
                    }
                }
            }
        catch(Exception e) { 
            e.printStackTrace();
        }
    }
}


Client:
Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.*;
 
public class TCPClient {
    
    static String clientName;
    static Socket clientSocket;
    static PrintWriter out;
    static BufferedReader in;
    static BufferedReader stdIn;
 
    public static void main(String[] args) throws IOException {
        
        clientSocket = new Socket("localhost", 8001);
        out = new PrintWriter(clientSocket.getOutputStream(), true);
        in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        stdIn = new BufferedReader(new InputStreamReader(System.in));
        
        //getNickname();
        
        new Thread() {
            @Override
            public void run() {
                while(true) {
                    try {
                        String mesage = in.readLine();
                        System.out.println(mesage);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            }.start();
            
            
        while(true) {
            String userMessage;
            userMessage = stdIn.readLine();
            out.write(userMessage + "\n");
            out.flush();
        }
        
        
    }
    
    
    private static void getNickname() throws IOException {
        System.out.print("Press your nick: ");
        clientName = stdIn.readLine();
    }
 
}
0
Эксперт функциональных языков программированияЭксперт Java
4485 / 2720 / 485
Регистрация: 28.04.2012
Сообщений: 8,585
06.12.2019, 20:58 8
Цитата Сообщение от sdasdaw Посмотреть сообщение
Ок, гугл сказал, что 49152-65535 - для пользователей
Для каких ещё пользователей? И при чём тут эти пользователи?

Цитата Сообщение от sdasdaw Посмотреть сообщение
А 1024-49151 - полу резервные, и тоже не стоит использовать для юзеров.
Для каких юзеров? Он сервис пишет, алё.

Цитата Сообщение от sdasdaw Посмотреть сообщение
Неа, у меня на линуксе было отказано в доступе с портом который у ТСа.
Твои линуксопроблемы.
0
-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716
06.12.2019, 21:01  [ТС] 9
Насчет линукса поддерживаю, для винды не очень важно, но в линухе не запустятся такие порты.
0
Эксперт функциональных языков программированияЭксперт Java
4485 / 2720 / 485
Регистрация: 28.04.2012
Сообщений: 8,585
06.12.2019, 23:03 10
Цитата Сообщение от SadiQ228 Посмотреть сообщение
да какого то фига надо флушить даже PrintWriter хотя в доках написано что не надо
А ты не заметил, что ты PrintWriter'ы по-разному создаёшь в сервере и клиенте? И вообще, ну и каша. На тебе черновик получше:

Server

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import java.io.*;
import java.net.*;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Supplier;
 
final class ChatServer {
 
    private static final Logger LOG = LoggerFactory.getLogger(ChatServer.class);
    private static final int PORT = 8001;
 
    private static final ExecutorService TASKS = Executors.newCachedThreadPool(r -> {
        final Thread t = new Thread(r, ChatServer.class.getSimpleName());
        t.setDaemon(true);
        return t;
    });
 
    public static void main(String[] args) throws IOException {
        final ServerSocket serverSocket = new ServerSocket(PORT);
        LOG.info("Listening on port " + PORT);
        final ConcurrentLinkedQueue<Client> clients = new ConcurrentLinkedQueue<>();
 
        while (true) {
            try {
                final Socket connection = serverSocket.accept();
                LOG.info("New client connected");
                TASKS.submit(() -> listen(() -> Client.create(connection, clients), clients));
            } catch (IOException e) {
                LOG.error("Cannot accept connection", e);
            }
        }
    }
 
    private static void listen(Supplier<Client> client, ConcurrentLinkedQueue<Client> clients) {
        try (Client c = client.get()) {
            while (true) {
                final String message = c.receive();
                if (message == null) {
                    LOG.info("Client closed connection");
                    break;
                }
                LOG.info("Received: {}", message);
                clients.forEach(listeningClient -> listeningClient.send(message));
            }
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }
 
    private static final class Client implements AutoCloseable {
 
        static Client create(Socket connection, ConcurrentLinkedQueue<Client> clients) {
            try {
                final BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                try {
                    final PrintWriter out = new PrintWriter(connection.getOutputStream(), true);
                    final Client client = new Client(clients, in, out);
                    clients.add(client);
                    return client;
                } catch (IOException e) {
                    closeSilently(in, "input stream");
                    throw e;
                }
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }
 
        private final ConcurrentLinkedQueue<Client> clients;
 
        private final BufferedReader in;
        private final PrintWriter out;
 
        private Client(ConcurrentLinkedQueue<Client> clients, BufferedReader in, PrintWriter out) {
            this.clients = clients;
            this.in = in;
            this.out = out;
        }
 
        @Override
        public void close() {
            clients.remove(this);
            closeSilently(in, "input stream");
            closeSilently(out, "output stream");
        }
 
        String receive() throws IOException {
            return in.readLine();
        }
 
        void send(String message) {
            out.println(message);
        }
 
        private static void closeSilently(Closeable c, String name) {
            try {
                c.close();
            } catch (Exception e) {
                LOG.warn("Error while closing client connection {}", name, e);
            }
        }
    }
}


Client

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import java.io.*;
import java.net.*;
 
final class ChatClient {
 
    private static final Logger LOG = LoggerFactory.getLogger(ChatClient.class);
 
    public static void main(String[] args) throws IOException {
        try (Socket connection = new Socket("localhost", 8001);
             PrintWriter server = new PrintWriter(connection.getOutputStream(), true)) {
            System.out.println("Connected");
            listen(connection);
            final BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
            String message;
            while ((message = input.readLine()) != null) {
                if (message.equals(":q")) {
                    break;
                }
                server.println(message);
            }
        }
    }
 
    private static void listen(Socket connection) {
        final Thread t = new Thread(() -> {
            try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
                while (connection.isConnected()) {
                    final String message = in.readLine();
                    if (message != null) {
                        System.out.println(": " + message);
                    }
                }
                LOG.info("Disconnected");
            } catch (SocketException e) {
                if (connection.isConnected()) {
                    LOG.error("Connection error", e);
                } else {
                    LOG.info("Disconnected", e);
                }
            } catch (IOException e) {
                LOG.error("Failed to read from server", e);
            }
        }, ChatClient.class.getSimpleName());
        t.setDaemon(true);
        t.start();
    }
}
Миниатюры
Многопользовательский TCP чат   Многопользовательский TCP чат  
2
Эксперт функциональных языков программированияЭксперт Java
4485 / 2720 / 485
Регистрация: 28.04.2012
Сообщений: 8,585
06.12.2019, 23:04 11
Цитата Сообщение от SadiQ228 Посмотреть сообщение
но в линухе не запустятся такие порты.
Какие такие? И что значит «не запустятся»?
0
-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716
06.12.2019, 23:05  [ТС] 12
означает что при компиляции выдаст эррор
за черновик спасибо ну ты уже взрослый дядя а я только учусь мне пока бы лишь бы работало и чтобы я это сам придумал
0
Эксперт функциональных языков программированияЭксперт Java
4485 / 2720 / 485
Регистрация: 28.04.2012
Сообщений: 8,585
07.12.2019, 00:22 13
Цитата Сообщение от SadiQ228 Посмотреть сообщение
означает что при компиляции выдаст эррор
Не выдаст.
1
07.12.2019, 00:22
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.12.2019, 00:22
Помогаю со студенческими работами здесь

Многопользовательский чат
Пишу элемент многопользовательского чата со страницы http://pblog.ru/?p=100 Просьба исправить...

Создать многопользовательский чат
Давно интересовался созданием мессенджера в командере. Создать мессенджер на самом то деле проще...

Многопользовательский чат на TcpClient
Решил написать чат. сервер: using System; using System.Collections.Generic; using...

Многопользовательский чат на Batch
Привет всем, имеется исходник: @rem BatChat @echo off cls pushd &quot;%~dp0&quot; echo Current DIR:...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru