-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

您的评估员错过了更重要的事情:它不起作用。您在服务器中的每个循环中调用 readObject() 两次,但您对第一个结果所做的只是使用 System.out.println() 将其打印出来。因此,您的代码缺少每个奇怪的对象。

您无能为力来提高速度。他可能希望您在 ObjectOutputStream 和套接字之间插入一个 BufferedOutputStream,对于 BufferedInputStream 也是如此。然而,对象流已经运行了它们自己的缓冲区,所以这可能是浪费时间。他可能还希望您使用大型套接字发送和接收缓冲区,如果您已经了解了这些:请参阅 Socket.setXXXBufferSize()。将它们设置为至少 32k。他也可能是反序列化的,但对于这个应用程序,我认为它没有太大的不同。这是一个交互式应用程序,消息很小,因此网络上的速度基本无关紧要。你只能打字这么快。

当用户键入告诉程序停止的任何内容时,您还应该在客户端中关闭,并且在服务器中,您必须在 IOException 之前捕获 EOFException,并在收到它时关闭套接字并跳出读取循环。

打印出 Socket.isConnected() 也不会产生有用的信息。套接字始终连接在您打印它的点。此方法不是对连接的健康检查,它只告诉您Socket的状态。不是一回事。

在我看来,您的评估员似乎专注于完全错误的事情。

于 2012-07-30T22:45:42.517 回答
0

我不确定您要花多少时间优化您的 Socket 代码,但 ZMQ http://www.zeromq.org/在消除延迟和优化带宽使用方面有很大帮助。

但是,在更简单的注释中。尽量不要使用 ObjectOutputStream 它们是上面的一层。立即使用 DataInputStream 和 DataOutputStream(也许还有 BufferedInputStream)对我来说已经有一段时间了,所以我生疏了。但是由于您正在发送字符串,因此您不需要随之进行对象序列化。

您说,您的时间也浪费在数据传输上。但请考虑不要在每个连接上创建新线程并使用线程池。

和萨拉姆。

于 2012-07-30T22:39:54.747 回答