Чат-сервер.Тема вопроса - PullRequest
       19

Чат-сервер.Тема вопроса

1 голос
/ 29 декабря 2011

Привет, может кто-нибудь помочь мне с этим кодом, потому что я пытался с оператором If, но не работает. Я не прошу писать для меня код, просто укажите мне на что-нибудь.

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

import java.net.*;
import java.io.*;

public class myServer {

    static ServerSocket server;
    static Socket client;
    static DataInputStream in;
    static DataOutputStream out;
    static clientThread t[] = new clientThread[10];

    public static void main(String[] args) throws IOException {

        System.out.println("Starting Server");
        server = new ServerSocket(7555);
        System.out.println("Started Server");

        while (true) {

            client = server.accept();
            System.out.println("CONNECTION");
            out = new DataOutputStream(client.getOutputStream());
            out.writeUTF("Welcome to the chat room");
            for (int i = 0; i <= 9; i++) {
                if (t[i] == null) {
                    (t[i] = new clientThread(client, t)).start();
                    break;
                }
            }
        }

    }

}

class clientThread extends Thread {

    DataInputStream in;
    DataOutputStream out;
    static String msg;
    Socket client = null;
    clientThread t[];

    public clientThread(Socket client, clientThread[] t) {
        this.client = client;
        this.t = t;
    }

    public void run() {

        try {
            in = new DataInputStream(client.getInputStream());
            out = new DataOutputStream(client.getOutputStream());
            boolean tru = true;

            while (tru) {
                msg = in.readUTF();
                System.out.println(msg);
                for (int i = 0; i <= 9; i++)
                    if (t[i] != null) {
                        t[i].out.writeUTF(msg);
                        System.out.println(t[i]);
                    }
            }
        } catch (IOException e) {
        }
    }
}

Ответы [ 3 ]

1 голос
/ 29 декабря 2011

Ваша проблема не в том, что поток остается включенным, а в том, что у вас нет механизма для пометки клиентских потоков как завершенных. Даже если поток завершен, t[i] не станет null. Он по-прежнему будет ссылаться на экземпляр потока - просто «мертвый» поток.

Вот два способа это исправить:

  1. Непосредственно перед выходом из вашего потока отметьте t[i] = null (где i - индекс текущего потока). Обратите внимание, что вам нужно хранить значение i в каждом потоке.

    1. Измените clientThread и добавьте private int threadIndex; в качестве переменной-члена.
    2. Измените конструктор clientThread и добавьте threadIndex в качестве параметра.

      public clientThread(Socket client, clientThread[] t, int threadIndex) 
      {
          this.threadIndex=threadIndex;
          //...
      }
      
    3. Прямо перед закрывающей скобкой run добавить

      synchronized(t){t[this.threadIndex]=null;}
      
  2. Используйте Executor и отправьте свои clientThread s. Java Executor s будет выполнять очистку потоков для вас.

1 голос
/ 29 декабря 2011

Почему вы создаете 10 потоков только для одного сокетного соединения?Я думаю, что вы хотите создать один ClientThread для каждого входящего соединения с сервером чата.Затем добавьте этот единственный ClientThread в список активных чатов.Когда клиент чата завершает сеанс, удалите запись из этого списка.Вам не нужно передавать экземпляр Thread или массив ClientThreads в конструктор ClientThread, поскольку он сам по себе.Просто передайте экземпляр Socket в ClientThread и ссылку на ChatServer.Если вы пытаетесь создать чат.Затем разрешите серверу обрабатывать отправку сообщения всем остальным:

public class ChatServer {
    List<ClientThread> activeParticipants;

    public void say( ClientThread author, String message ) {
        for( ClientThread current : activeParticipants ) {
           if( current != author ) {
              current.send( message ); // this method will send a message to that client
           }
        }
    }
}

Вам нужно будет либо использовать два потока, либо использовать метод InputStream.available (), чтобы проверить, есть ли какой-либо вход для одного из них.System.in или входной поток вашего сокета.Это позволит вам читать входящие сообщения, а также позволять пользователю одновременно печатать сообщения.Блокировка метода read () будет означать, что вы не сможете видеть сообщения, пока не введете некоторые данные или не получите данные.

Также переместите приветственное сообщение в ClientThread, чтобы не вызывать Socket.getOutputStream () дважды, используядва разных объекта DataOutputStreams.

0 голосов
/ 29 декабря 2011

Вы вызываете метод client.getOutputStream () дважды, каждый раз создавая DataOutputStream.Попробуйте приветствовать пользователя прямо в ClientThread.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...