Форум программистов, компьютерный форум, киберфорум
Java: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.52/25: Рейтинг темы: голосов - 25, средняя оценка - 4.52
 Аватар для SadiQ228
-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716

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

06.12.2019, 01:32. Показов 5367. Ответов 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,765
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,765
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,765
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,765
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,765
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
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru