11 / 11 / 10
Регистрация: 06.10.2012
Сообщений: 675

TCP чат на 2 и более пользователей

13.04.2014, 15:48. Показов 5348. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Нужно сделать чат на двух и более пользователей. Сервер принимает данные только от одного пользователя. Как сделать сервер многопоточный? Помогите исправить:
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
import java.io.*;
import java.net.*;
 
public class main1_11Server extends Thread{
 
 
 
    public static void main(String[] args) throws IOException {
        //привинчиваем сокет на локалхост с портом
        Thread thread = new Thread();
        ServerSocket server = new ServerSocket(5050, 0, InetAddress.getByName("localhost"));
 
        System.out.println("Server start.");
 
        while (true)
        {
            Socket clientSocket = server.accept();
            new talker(clientSocket).thread.start();
        }
    }
}
 
class talker
{
    private Socket client;
    public Thread thread;
 
    public talker(Socket client) throws IOException
    {
        this.client = client;
        run();
 
    }
 
    public void run() throws IOException {
        BufferedReader input = new BufferedReader(new InputStreamReader(client.getInputStream()));
        try {
            while (true){
                String data = input.readLine();
                if (data != null)
                    System.out.println("Server: " + data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
Добавлено через 20 минут
Исправил. получилось вот так:
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
import java.io.*;
import java.net.*;
 
public class main1_11Server extends Thread{
 
 
 
    public static void main(String[] args) throws IOException {
        //привинчиваем сокет на локалхост с портом
        Thread thread = new Thread();
        ServerSocket server = new ServerSocket(5050, 0, InetAddress.getByName("localhost"));
 
        System.out.println("Server start.");
 
        while (true)
        {
            Socket clientSocket = server.accept();
            new talker(clientSocket);
        }
    }
}
 
class talker extends Thread
{
    private Socket client;
    private BufferedReader input;
 
    public talker(Socket client) throws IOException
    {
        this.client = client;
        input = new BufferedReader(new InputStreamReader(client.getInputStream()));
        start();
       // run();
 
    }
 
    public void run(){
 
        try {
            while (true){
                String data = input.readLine();
                if (data != null)
                    System.out.println("Server: " + data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
Присылать могут как минимум 3 клиента. Но вот вопрос: пришло сообщение от одного пользователя, как сделать чтобы сервер пересылал это сообщение всем остальным клиентам?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
13.04.2014, 15:48
Ответы с готовыми решениями:

Чат для 3 и более пользователей
Как можно организовать рассылку сообщений сразу двоим пользователям? Как создать некую сеть из троих (или более) человек? Например, есть...

Чат на tcp/ip
Хочу написать чат на tcp/ip. Но не могу додуматься как реализовать чисто логически кое-какие действия. Получается так: Допустим есть...

TCP чат
добрый день, решил написать онлайн чат. все вроде бы сделал, но в ходе работы вылазиют непонятные ошибки, кто может помочь (ошибка в 141...

15
 Аватар для IVIakCollideR
40 / 40 / 14
Регистрация: 26.12.2013
Сообщений: 309
13.04.2014, 16:07
нужно создать список с набором выходных потоков всех подключившихся к серверу клиентов, потом когда принимаешь сообщение, пробегаешься итератором по списку, присваиваешь обьекты выходных потоков новым PrintWriter-ам и отсылаешь сообщение
0
11 / 11 / 10
Регистрация: 06.10.2012
Сообщений: 675
13.04.2014, 16:46  [ТС]
Цитата Сообщение от IVIakCollideR Посмотреть сообщение
нужно создать список с набором выходных потоков всех подключившихся к серверу клиентов, потом когда принимаешь сообщение, пробегаешься итератором по списку, присваиваешь обьекты выходных потоков новым PrintWriter-ам и отсылаешь сообщение
Создал вот так, а вот как отправить немогу понять почему так нельзя.
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
class talker extends Thread
{
    private Socket client;
    private BufferedReader input;
    private PrintStream output;
 
    public talker(Socket client) throws IOException
    {
        this.client = client;
        input = new BufferedReader(new InputStreamReader(client.getInputStream()));
        output = new PrintStream(client.getOutputStream());
        start();
    }
 
    public void run(){
 
        try {
            while (true){
                String data = input.readLine();
                if (data != null)
                {
                    System.out.println("Server: " + data);
 
                    synchronized (main1_11Server.connections){
                        Iterator<Connection> iterator = main1_11Server.connections.iterator();
                        while (iterator.hasNext()){
                            ((Connection)iterator.next()).output.println(data);
                        }
                    }
                }
 
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
Ругается на ((Connection)iterator.next()).output.pri ntln(data);
Что не так?

Добавлено через 3 минуты
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static List<Connection> connections = Collections.synchronizedList(new ArrayList<Connection>());
 
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(5050, 0, InetAddress.getByName("localhost"));
 
        System.out.println("Server start.");
 
        while (true)
        {
            Socket clientSocket = server.accept();
            talker tal = new talker(clientSocket);
            connections.add((Connection) tal);
        }
    }
0
 Аватар для IVIakCollideR
40 / 40 / 14
Регистрация: 26.12.2013
Сообщений: 309
13.04.2014, 18:08
лучше создавайте ArrayList/
метод отправки будет выглядеть примерно так
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
public void tellEveryone(String message){//message - передается меседж от клиента который будет рассылаться всем
        Iterator i = connections.iterator();//сам список connections создай в виде поля класса "сервер" (или талкер, как от там у тебя называется)
        while(i.hasNext()){
            try{
                PrintWriter pw = (PrintWriter) i.next();
                pw.println(message);
                pw.flush();
            }catch(Exception ex){
                System.out.println("error in iterator");
                ex.printStackTrace();
            }
        }
    }
0
11 / 11 / 10
Регистрация: 06.10.2012
Сообщений: 675
13.04.2014, 19:14  [ТС]
Цитата Сообщение от IVIakCollideR Посмотреть сообщение
лучше создавайте ArrayList/
Сделал как вы сказали. Но вот с добавление туда пользователей проблемы:
Java
1
2
3
4
5
6
7
public static ArrayList<Connection> connections = new ArrayList<Connection>();
 while (true)
        {
            Socket clientSocket = server.accept();
            talker tal = new talker(clientSocket);
            connections.add((Connection)tal);
        }
Или я что-то не то делаю?
0
 Аватар для IVIakCollideR
40 / 40 / 14
Регистрация: 26.12.2013
Сообщений: 309
13.04.2014, 19:54
понятно что не так, добавлять нужно ВЫХОДНОЙ ПОТОК
примерно так
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Server{
ArrayList connections;
.......
 
public main(){
new Server().go
}
 
public void go(){
        connections = new ArrayList();
        try{
            ServerSocket servSock = new ServerSocket(5050);
            while(true){
                Socket socket = servSock.accept();
                PrintWriter pw = new PrintWriter(socket.getOutputStream());
                connections.add(pw);
            }
        }catch(Exception ex){
            System.out.println("error in @go@ !");
            ex.printStackTrace();
        }
    }
Добавлено через 1 минуту
но придется создать еще один поток, что бы сервер мог одновременно принимать и отсылать сообщения
1
ɐwʎ ɔ vǝmоɔ dиw ɐʚонɔ
 Аватар для tankomaz
443 / 442 / 100
Регистрация: 14.10.2012
Сообщений: 1,146
Записей в блоге: 9
13.04.2014, 23:05
в соседней теме мой примерчик гляньте https://www.cyberforum.ru/java... 47180.html
0
11 / 11 / 10
Регистрация: 06.10.2012
Сообщений: 675
14.04.2014, 00:02  [ТС]
Цитата Сообщение от tankomaz Посмотреть сообщение
в соседней теме мой примерчик гляньте Коллекция и TCP сервер
Спасибо вам огромное. А можете ещё помочь с клиентом.
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
import java.io.*;
import java.net.*;
import java.util.Scanner;
 
public class main1_11Client extends Thread{
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        Socket socket = null;
        try
        {
            socket = new Socket("localhost", 5050);
            PrintStream output = new PrintStream(socket.getOutputStream());
 
            while (true)
            {
                String str = sc.nextLine();
                output.println(str);
                output.flush();
 
                BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String data = input.readLine();
                System.out.println(data);
 
            }
        }
        catch (Exception e)
        {
            System.out.println(e);
        }finally {
            if (socket != null)
                socket.close();
        }
    }
}
Дело в том что сервер работает (отправил и принял). Т.е. как можно сделать что-бы он был в режиме принятия и отправки данных в любой момент. На данный момент пока я не отправлю данные клиент ничего не приимет. А нужно пришло одно сообщение другое, захотел я отправить данные - отправил и дальше смотрю переписку других клиентов...
0
ɐwʎ ɔ vǝmоɔ dиw ɐʚонɔ
 Аватар для tankomaz
443 / 442 / 100
Регистрация: 14.10.2012
Сообщений: 1,146
Записей в блоге: 9
14.04.2014, 00:40
клиент на мою версию сервера? в таком случае он немного для этого не подходит
0
11 / 11 / 10
Регистрация: 06.10.2012
Сообщений: 675
14.04.2014, 18:52  [ТС]
Цитата Сообщение от tankomaz Посмотреть сообщение
клиент на мою версию сервера? в таком случае он немного для этого не подходит
Вот мой сервер:
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.*;
import java.net.*;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
 
public class main1_11Server extends Thread{
    public static ArrayList connections = new ArrayList();
 
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(5050, 0, InetAddress.getByName("localhost"));
 
        System.out.println("Server start.");
 
        while (true)
        {
            Socket clientSocket = server.accept();
            PrintWriter pw = new PrintWriter(clientSocket.getOutputStream());
            talker tal = new talker(clientSocket);
            connections.add(pw);
        }
    }
}
 
class talker extends Thread
{
    private Socket client;
    private BufferedReader input;
    private PrintStream output;
 
    public talker(Socket client) throws IOException
    {
        this.client = client;
        input = new BufferedReader(new InputStreamReader(client.getInputStream()));
        output = new PrintStream(client.getOutputStream());
        start();
    }
 
    public void run(){
 
        try {
            while (true){
                String data = input.readLine();
                if (data != null)
                {
                    System.out.println("Server: " + data);
 
                    Iterator iterator = main1_11Server.connections.iterator();
                    while (iterator.hasNext())
                    {
                        PrintWriter pw = (PrintWriter) iterator.next();
                        pw.println(data);
                        pw.flush();
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
0
 Аватар для IVIakCollideR
40 / 40 / 14
Регистрация: 26.12.2013
Сообщений: 309
14.04.2014, 19:11
Цитата Сообщение от Vla00 Посмотреть сообщение
захотел я отправить данные - отправил и дальше смотрю переписку других клиентов...
не совсем понял что это у вас за сервер,
если ориентироваться по заголовку темы, то вам нужен сервер который принимает сообщение и отсылает всем остальным, или тз поменялось?
0
11 / 11 / 10
Регистрация: 06.10.2012
Сообщений: 675
14.04.2014, 21:55  [ТС]
Цитата Сообщение от IVIakCollideR Посмотреть сообщение
отсылает всем остальным, или тз поменялось?
Нет не поменялось. Нужно создать чат на много пользователей. Но дело в том что, клиент у меня пока неправильно работает. (клиент)Когда я отсылаю сообщение он его отсылает на сервер и принимает то что мы отправили (сервер это сообщение рассылает всем пользователям). Но мы не можем принимать сообщения пока не введём, таким образом мы принимаем только то сообщение которое мы отослали, от других пользователей мы не можем принять, так как клиент ждёт пока мы ведём сообщение.... Думаю вы поняли в чём дело.)
0
 Аватар для IVIakCollideR
40 / 40 / 14
Регистрация: 26.12.2013
Сообщений: 309
14.04.2014, 22:10
Цитата Сообщение от Vla00 Посмотреть сообщение
так как клиент ждёт пока мы ведём сообщение
мб сервер ждет?
сервер должен висеть в потоке и ждать сообщения от клиентов, клиенты отправляют смс, потом сервер читает и отправляет это смс обратно всем клиентам и тд. у вас не так работает?
0
ɐwʎ ɔ vǝmоɔ dиw ɐʚонɔ
 Аватар для tankomaz
443 / 442 / 100
Регистрация: 14.10.2012
Сообщений: 1,146
Записей в блоге: 9
14.04.2014, 22:21
readLine() стоппет, повнсьте InputStream в новый поток, а основной пусть следит за вами
0
 Аватар для IVIakCollideR
40 / 40 / 14
Регистрация: 26.12.2013
Сообщений: 309
14.04.2014, 22:40
У вас распределение ресурсов кривое.
так должно работать
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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;
 
public class main1_11Server {
    public ArrayList connections;
 
    public static void main(String[] args) {
        new main1_11Server().go();
    }
 
    public void go() {
        connections = new ArrayList();
        try {
            ServerSocket server = new ServerSocket(5050);
            System.out.println("Server start.");
 
            while (true) {
                Socket clientSocket = server.accept();
                PrintWriter pw = new PrintWriter(clientSocket.getOutputStream());
                connections.add(pw);
 
                Thread thread = new Thread(new Talker(clientSocket));
                thread.start();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
 
    class Talker implements Runnable {
 
        BufferedReader breader;
        Socket sock;
 
        Talker(Socket clientSocket) {
            try {
                sock = clientSocket;
                InputStreamReader sreader = new InputStreamReader(sock.getInputStream());
                breader = new BufferedReader(sreader);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
 
        public void run() {
            String message;
            try {
                while ((message = breader.readLine()) != null) {
                    System.out.println("serv read " + message);
                    tellEveryone(message);
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
 
        public void tellEveryone(String message) {
            Iterator i = connections.iterator();
            while (i.hasNext()) {
                try {
                    PrintWriter pw = (PrintWriter) i.next();
                    pw.println(message);
                    pw.flush();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}
0
11 / 11 / 10
Регистрация: 06.10.2012
Сообщений: 675
15.04.2014, 00:29  [ТС]
Цитата Сообщение от IVIakCollideR Посмотреть сообщение
У вас распределение ресурсов кривое.
так должно работать
С сервером всё нормально, но вот с клиентов не так....

Добавлено через 1 час 2 минуты
Решение сделал такое:
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
import java.io.*;
import java.net.*;
import java.util.Scanner;
 
public class main1_11Client extends Thread{
    public static void main(String[] args) throws IOException {
        Socket socket = null;
        try
        {
            socket = new Socket("localhost", 5050);
            new Output(socket);
            new Input(socket);
        }
        catch (Exception e)
        {
            System.out.println(e);
        }
    }
}
 
class Output extends Thread{
    private Socket socket;
    private Scanner in;
    private PrintWriter out;
 
    public Output(Socket s) throws IOException{
        socket = s;
        in = new Scanner(System.in);
        out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()), true);
        start();
    }
 
    public void run(){
        while(true){
            System.out.print("U: ");
            String data = in.nextLine();
            if(data.equals("END")) {
                break;
            }
            out.println(data);
        }
    }
}
 
class Input extends Thread{
    private Socket socket;
    private BufferedReader in;
 
    public Input(Socket s) throws IOException{
        socket = s;
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        start();
    }
 
    public void run(){
        try {
            while(true){
                String data = in.readLine();
                System.out.println("from: " + data);
            }
        }catch (IOException e){
            e.printStackTrace();
        }
 
    }
}
Может кому-то понадобиться)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
15.04.2014, 00:29
Помогаю со студенческими работами здесь

TCP-Чат
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using...

Чат на протоколе TCP
Доброго времени суток Пишу чат на протоколе TCP и столкнулся с такой проблемой: дублируется сообщение себе же... то есть я пишу, как...

Многопользовательский TCP чат
Для отправки сообщений юзаю PrintWriter, поэтому flush'ить не надо. Вижу на сервере что юзеры подсоединяются, но сообщения не...

TCP чат-сервер
Здравствуйте! Нужна помощь с таким заданием: На базе шаблона параллельного эхо-сервера, использующего модель “один клиент - один поток”,...

Чат на сокетах (TCP)
как реализовать? в принципе работал с сокетами, но не понимаю как конкретно чат делается? ведь всегда должен быть сервер по идее, я могу...


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

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

Новые блоги и статьи
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
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 Использованы. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru