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

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

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

Студворк — интернет-сервис помощи студентам
Для отправки сообщений юзаю 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)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
06.12.2019, 01:32
Ответы с готовыми решениями:

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

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

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

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

Решение

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

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

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

Добавлено через 59 секунд
Цитата Сообщение от SadiQ228 Посмотреть сообщение
подставил флаги результата нету
А flush?
1
 Аватар для SadiQ228
-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716
06.12.2019, 20:58  [ТС]
да какого то фига надо флушить даже 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
 Аватар для korvin_
4575 / 2774 / 491
Регистрация: 28.04.2012
Сообщений: 8,779
06.12.2019, 20:58
Цитата Сообщение от sdasdaw Посмотреть сообщение
Ок, гугл сказал, что 49152-65535 - для пользователей
Для каких ещё пользователей? И при чём тут эти пользователи?

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

Цитата Сообщение от sdasdaw Посмотреть сообщение
Неа, у меня на линуксе было отказано в доступе с портом который у ТСа.
Твои линуксопроблемы.
0
 Аватар для SadiQ228
-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716
06.12.2019, 21:01  [ТС]
Насчет линукса поддерживаю, для винды не очень важно, но в линухе не запустятся такие порты.
0
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4575 / 2774 / 491
Регистрация: 28.04.2012
Сообщений: 8,779
06.12.2019, 23:03
Цитата Сообщение от 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
 Аватар для korvin_
4575 / 2774 / 491
Регистрация: 28.04.2012
Сообщений: 8,779
06.12.2019, 23:04
Цитата Сообщение от SadiQ228 Посмотреть сообщение
но в линухе не запустятся такие порты.
Какие такие? И что значит «не запустятся»?
0
 Аватар для SadiQ228
-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716
06.12.2019, 23:05  [ТС]
означает что при компиляции выдаст эррор
за черновик спасибо ну ты уже взрослый дядя а я только учусь мне пока бы лишь бы работало и чтобы я это сам придумал
0
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4575 / 2774 / 491
Регистрация: 28.04.2012
Сообщений: 8,779
07.12.2019, 00:22
Цитата Сообщение от SadiQ228 Посмотреть сообщение
означает что при компиляции выдаст эррор
Не выдаст.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
07.12.2019, 00:22
Помогаю со студенческими работами здесь

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

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

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

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

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


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

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

Новые блоги и статьи
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru