-2

私はマルチクライアントに関する大学の研究プロジェクトの一部をプログラムしようとしています-サーバーソケットプログラミング。私のコードは同様に機能するので、有効な結果が得られますが、問題は、私たちのグループの評価者が私のコードの速度が良くないと言ったことですこの問題の原因となる問題をコードで見つけた場合は、データ転送の接続に感謝します。

サーバー部分:

    import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import j

ava.io.PrintStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;

/**
 * 
 */

/**
 * @author Sina
 *
 */
public class BoxServer {

    ServerSocket serversocket;
    static ThreadHandler t[]=new ThreadHandler[100];
    static int size=0;
    static ArrayList<Message> messagebox=new ArrayList<Message>();
    public static void main(String[] args) {

        ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket(79);
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        while(true)
        {

        try{




                //InetAddress inetadress=InetAddress.getLocalHost();
                //System.out.println(inetadress);
                //System.out.println(inetadress.getHostName());
                //System.out.println(inetadress.getHostAddress());
                Socket socket=serverSocket.accept();
                if(socket==null)
                {
                    System.out.println("null");
                }
                t[size]=new ThreadHandler(socket,"username");
                size++;
                t[size-1].start();



        }
        catch(UnknownHostException e){
            System.out.println("salam s");
         System.out.println(e.getMessage());
        }
        catch (IOException e) {
            System.out.println("bye s");
            System.out.println(e.getMessage());
        }


        }

    }

}

class ThreadHandler extends Thread{

    private String socname;
    Socket mySocket;
    ObjectInputStream inp;
    ObjectOutputStream outp;
    public ThreadHandler(Socket s,String socketName)
    {
        this.mySocket=s;
        this.socname=socketName;



    }
    public void run()
    {
        try {
            inp=new ObjectInputStream(mySocket.getInputStream());
            outp=new ObjectOutputStream(mySocket.getOutputStream());
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        while(true)
        {
        System.out.println("thread run");
        System.out.println(mySocket.getLocalPort());
        System.out.println(mySocket.getLocalAddress());

        try {
        //  System.out.println("my socket:"+mySocket.getOutputStream());
            System.out.println(mySocket.isConnected());
            System.out.println(inp.available());
            System.out.println("inp = "+inp);
            System.out.println("reeead "+ inp.readObject());
            Message mess=(Message)inp.readObject();
            System.out.println("dsd");
            System.out.println("mess: "+mess);
            BoxServer.messagebox.add(mess);
            if(mess.getReceiver().equals("system-use:code=1"))
            {
                System.out.println(mess.getSender()+" wants to see his/her Inbox");
            }
            //mySocket.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            System.out.println("bug dar thread");
            e.printStackTrace();

        }

         }

    }
}

クライアント部分

    import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
import java.util.TimerTask;
import java.util.concurrent.ScheduledExecutorService;

import javax.swing.Timer;

public class Main {

    /**
     * @param args
     */


    static Socket socket=new Socket();
    public static void main(String[] args) {




        System.out.println("newuser(n) or login(l)");
        Scanner scanner=new Scanner(System.in);
        String typeOfOperation=scanner.nextLine();
        if(typeOfOperation.equals("n"))
        {


        }
        else
        if(typeOfOperation.equals("l"))
        {

            try {
                socket = new Socket("127.0.0.1",79);
                final ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
                ObjectInputStream in=new ObjectInputStream(socket.getInputStream());

                while(true)
                {

                Thread timer=new Thread()
                {
                    public void run()
                    {
                        while(true)
                        {
                            Message temp=new Message();
                            temp.setReceiver("system-use:code=1");
                            temp.setSender("username");

                            try {
                                out.writeObject(temp);
                                sleep(5000);
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            catch (InterruptedException e) {
                                // TODO: handle exception
                                e.printStackTrace();
                            }

                        }
                    }
                };
                timer.start();
                String username=scanner.nextLine();
                String to=scanner.nextLine();
                String body=scanner.nextLine();
                Message all=new Message();
                all.setText(body);
                all.setReceiver(to);
                all.setSender(username);


                System.out.println("you connected to system");
                System.out.println(socket);

                System.out.println("now should write");
                out.writeObject(all);
                System.out.println("ghable threAD");

                }
            //  socket.close();

            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                System.out.println("salaam c");
                System.out.println(e.getMessage());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                System.out.println("bye c");
                System.out.println(e.getMessage());
            }

        }
        else
        {
            System.out.println("bad operation. try again!");
        }


    }

}

メッセージクラス(エンティティは重要ではないと思います!):

import java.io.Serializable;


public class Message implements Serializable{
    String sender;
    String receiver;
    String text;
    boolean delivered=false;
    public void delived()
    {
        this.delivered=true;
    }
    private String tostringOfClass;

    public void setReceiver(String receiver) {
        this.receiver = receiver;
    }
    public void setSender(String sender) {
        this.sender = sender;
    }
    public void setText(String text) {
        this.text = text;
    }
    public String getReceiver() {
        return receiver;
    }
    public String getSender() {
        return sender;
    }
    public String getText() {
        return text;
    }

    public String toString()
    {
        tostringOfClass="sender : "+sender+" \n"+"receiver : "+receiver+" \n"+"message: "+text;

        return tostringOfClass;
    }

}
4

2 に答える 2

3

あなたの評価者はもっと重要な何かを見逃しました:それは機能しません。サーバーでループごとに2回readObject()を呼び出していますが、最初の結果で行うのは、System.out.println()で出力することだけです。したがって、コードにはすべての奇妙なオブジェクトがありません。

これの速度を改善するためにあなたができることはあまりありません。彼はおそらく、ObjectOutputStreamとソケットの間にBufferedOutputStreamを挿入することを望んでいます。同様に、BufferedInputStreamの場合も同様です。ただし、オブジェクトストリームはすでに独自のバッファを実行しているため、これはおそらく時間の無駄です。また、大きなソケットの送信バッファと受信バッファについて教えられている場合は、それらを使用することをお勧めします。Socket.setXXXBufferSize()を参照してください。それらを少なくとも32kに設定します。彼は反シリアル化でもあるかもしれませんが、このアプリケーションでは、それが大きな違いを生むとは思いません。これはインタラクティブなアプリケーションであり、メッセージが小さいため、ネットワーク上の速度は基本的に関係ありません。あなたはとても速くタイプすることができるだけです。

また、ユーザーがプログラムの停止を指示する内容を入力したときにクライアントを閉じ、サーバーではIOExceptionの前にEOFExceptionをキャッチし、ソケットを閉じて読み取りループを終了する必要があります。

また、Socket.isConnected()を出力しても、有用な情報は得られません。ソケットは、印刷した場所で常に接続されています。このメソッドは、接続のヘルスチェックではなく、ソケットの状態についてのみ通知します。同じことではありません。

あなたの評価者は私には完全に間違ったことに焦点を合わせているようです。

于 2012-07-30T22:45:42.517 に答える
0

ソケットコードの最適化にどれだけの時間を費やしたいかはわかりませんが、ZMQ http://www.zeromq.org/は、レイテンシーの除去と帯域幅の使用の最適化に大いに役立ちました。

ただし、より単純なメモでは。1つ上のレイヤーであるObjectOutputStreamを使用しないようにしてください。DataInputStreamとDataOutputStream(おそらくBufferedInputStreamも)にすぐに行きます私にとっては久しぶりなので、さびています。ただし、文字列を送信しているため、オブジェクトのシリアル化を一緒に行う必要はありません。

あなたは、データ転送でもあなたの時間が失われていると言いました。ただし、接続ごとに新しいスレッドを作成せず、スレッドプールを使用することを検討してください。

とサラム。

于 2012-07-30T22:39:54.747 に答える