1

参考までにこれは宿題です。Javaチャットサーバーを構築する必要があります。1つのクライアントと通信するサーバーを構築することができました。しかし、私は複数のユーザーと通信するためにこれが必要です。

ユーザーは、話したい相手の名前を入力し、その後にダッシュ(-)を入力してから、送信するメッセージを入力する必要があります。ユーザーをサインオンさせることはできますが、印刷するユーザーのリストや他のユーザーに送信するメッセージを取得することはできません。サーバーコードは次のとおりです。

/** 
    Threaded Server
*/

import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Set;

public class ThreadedServer
{
    public static void main( String[] args) throws Exception
    {
        HashMap<String, Socket> users = new HashMap<String, Socket>( );
        ServerSocket server = new ServerSocket(5679);
        System.out.println( "THE CHAT SERVER HAS STARTED! =)" );
        while(true)
        {
            Socket client = server.accept();
            ThreadedServer ser = new ThreadedServer();
            ClientFromThread cft =ser.new ClientFromThread(client);
            String name = cft.getUserName();
            users.put( name, client );
            cft.giveUsersMap( users );
            //cft.giveOnlineUsers( ); //DOES NOT WORK YET!!!!
            System.out.println("Threaded server connected to " 
                        + client.getInetAddress() + "  USER: " + name );            
        } 

    }

    //***************************************************************************************************

    class ClientFromThread extends Thread
    {
        private Socket client;
        private Scanner fromClient;
        private PrintWriter toClient;
        private String userName;
        HashMap<String, Socket> users;

        public ClientFromThread( Socket c ) throws Exception
        {
            client = c;
            fromClient = new Scanner( client.getInputStream() );
            toClient = new PrintWriter( client.getOutputStream(), true );
            userName = getUser();
            start();
        }
        public void giveUsersMap( HashMap<String, Socket> users )
        {
            this.users = users;
        }

        //THIS DOESNT WORK YET... IT PRINTS THE FIRST LINE BUT NOT THE LIST
        public void giveOnlineUsers()
        {
            toClient.println("These users are currently online:");
            Set<String> userList = users.keySet();
            String[] userNames = null;
            userList.toArray( userNames );

            for( int i = 0; i< userNames.length; i++ )
            {
                toClient.println(userNames[i]);
            }
        }

        public String getUserName()
        {
            return userName;
        }

        private String getUser()
        {
            String s = "";
            while( (s.length() < 1) || (s == null) )
            {
                toClient.println("What is your first name? ");
                s=fromClient.nextLine().trim();
            }
            toClient.println("Thank You! Welcome to the chat room " + s + ".");
            return s.toUpperCase();
        }

        public void run() 
        {
            String s = null;
            String toUser;
            String mesg;

            while( (s=fromClient.nextLine().trim()) != null )
            {
                if( s.equalsIgnoreCase( "END" )) break;

                for( int i=0; i<s.length(); i++)
                {
                    if( s.charAt(i) == '-' )
                    {
                        toUser = s.substring( 0, i ).trim().toUpperCase();
                        mesg = s.substring( i+1 ).trim();
                        Socket client = users.get( toUser );
                        try
                        {
                            ClientToThread ctt = new ClientToThread(client);
                            ctt.sendMesg( mesg, toUser );
                            ctt.start();
                        }
                        catch(Exception e){e.printStackTrace();}
                        break;
                    }
                    if( (i+1) == s.length() )
                    {
                        toClient.println("Sorry the text was invalid. Please enter a user name " +
                                                     "followed by a dash (-) then your message.");
                    }
                }
            }
            try
            {
                fromClient.close();
                toClient.close();
                client.close();
            }
            catch(Exception e){e.printStackTrace();}
        }

    } //end class ClientFromThread

    //***************************************************************************************************

    class ClientToThread extends Thread
    {
        private Socket client;
        private PrintWriter toClient;
        private String mesg;

        public ClientToThread( Socket c ) throws Exception
        {
            client = c;
            toClient = new PrintWriter( client.getOutputStream(), true );
        }

        public void sendMesg( String mesg, String userName )
        {
            this.mesg = userName + ": " + mesg;
        }
        public void run() 
        {
            toClient.println(mesg);

            try
            {
                toClient.close();
                client.close();
            }
            catch(Exception e){e.printStackTrace();}
        }

    } //end class ClientToThread

    //***************************************************************************************************

} //end class ThreadedServer

これがクライアントコードです」

import java.net.Socket;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;


public class ReverseClient 
{
public static void main( String[] args ) throws Exception
{
    String line = null;
    Socket server= new Socket( "10.0.2.103", 5679);
    System.out.println( "Connected to host: " + server.getInetAddress() );
    BufferedReader fromServer = new BufferedReader(
                new InputStreamReader(server.getInputStream()) );
    PrintWriter toServer = new PrintWriter( server.getOutputStream(), true );
    BufferedReader input = new BufferedReader( 
                new InputStreamReader(System.in) );
    while( (line=input.readLine()) !=null )
    {
        toServer.println(line);
        System.out.println( fromServer.readLine() );
    }
    fromServer.close();
    toServer.close();
    input.close();
    server.close();

}   
}

これがコンソール出力です(上がサーバー、下がクライアントです): 代替テキスト

(上の画像に示されているように)エラーが発生し、メッセージが送信されません。これらの問題に対処する方法について何か提案はありますか?

4

2 に答える 2

1

これまでのところ、これが問題であることがわかりましたが、これが唯一の問題ではないと思います。

これは、90行目あたりのNoSuchElementExceptionに役立ちます。これを変更してください...

while( (s=fromClient.nextLine().trim()) != null )
{

これに...

while(fromClient.hasNext())
{
   s = fromClient.nextLine().trim();

OK、ClientToThread.run()で別の問題が見つかりました...最初のメッセージを送信した後、クライアント接続を閉じています。私はそれらの両方をコメントアウトしました、そしてそれは少し良く働いているようです。

public void run()
  {
     toClient.println(mesg);
     try {
        //toClient.close();
        //client.close();
     }
     catch (Exception e)  {
        e.printStackTrace();
     }
  }
于 2009-10-18T03:09:29.507 に答える
0

最初の問題は、ユーザーからのメッセージの解析にあります。

文字列をループすると、文字がダッシュであるか無効であるかの2つのオプションのいずれかがあります。

したがって、理想的には、ダッシュの前のユーザー名の文字数に対して無効なメッセージが表示されるはずです。

String.indexOfを使用してダッシュの場所を特定し、メッセージを2つの部分に分割する必要があります。また、indexOfの結果が-1の場合、それは無効なメッセージです。

于 2009-10-18T03:03:06.197 に答える