2012-07-30 28 views
-2

我嘗試編寫關於多客戶端 - 服務器套接字編程的一個大學研究項目的一部分。我的代碼的工作原理以及我給出的結果是好的,但問題在於我們組的評估者說我的代碼不好連接數據傳輸的速度。如果您在我的代碼中發現導致此問題的問題,我會很感激。在Java中優化套接字編程的最佳方法?

服務器部分:

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; 
    } 

} 
+0

@Downvoters和密切的選民:請解釋。這在什麼方面不是一個真正的問題? – EJP 2012-07-30 22:47:45

+1

我還沒有關閉投票,但表格「這是我的代碼,請告訴我什麼是錯誤」的問題通常被認爲「不具有建設性」。OP必須顯示一些試圖解決他/她自身問題的證據。 – 2012-07-31 03:35:54

回答

3

您的評估者錯過了更重要的一件事:它不起作用。你在服務器的每個循環中調用readObject()兩次,但是你所做的第一個結果是用System.out.println()打印出來。所以你的代碼缺少每個奇怪的對象。

你可以做些什麼來提高速度。他可能希望你在ObjectOutputStream和套接字之間插入一個BufferedOutputStream,對於BufferedInputStream也是如此。但是對象流已經運行了自己的緩衝區,所以這可能是浪費時間。他可能還希望你使用大的套接字發送和接收緩衝區,如果你已經被教過這些:請參閱Socket.setXXXBufferSize()。將它們設置爲至少32k。他也可能是反序列化,但對於這個應用程序,我沒有看到它有什麼不同。這是一個交互式應用程序,消息很小,所以網絡上的速度基本上是不相關的。你只能輸入這麼快。

如果用戶鍵入告訴程序停止的任何東西,那麼您還應該在客戶端中關閉;而在服務器中,您必須捕獲EOFException,在IOException之前關閉套接字並在您讀取循環時跳出得到它。

也打印出Socket.isConnected()不會產生有用的信息。套接字始終在打印點上連接。此方法不是連接的健康檢查,它只會告訴您有關套接字的狀態。不是一回事。

您的評估者似乎把我的注意力集中在完全錯誤的事情上。

+0

非常感謝你..意思helpfull – Sina 2012-07-31 06:53:35

+0

另一件事是我真的給所有測試!我今天親自嘗試!我會再次閱讀我的代碼,也許有一些錯誤,我沒有看到奇怪的物體! – Sina 2012-07-31 07:00:09

+0

+1我會擔心在寫入相同輸出流的無限循環中創建線程。我只能假設這個程序還沒有經過測試。 – 2012-07-31 07:36:30

0

我不知道多少時間你會想投資於優化你的Socket代碼,但ZMQ http://www.zeromq.org/在消除延遲並優化帶寬使用。

然而,在更簡單的筆記。儘量不要使用ObjectOutputStream,它們是上面的一層。立即去DataInputStream和DataOutputStream(也可能是BufferedInputStream)這對我來說已經有一段時間了,所以我很生疏。但是,由於您正在發送字符串,因此您無需與對象序列化一起進行。

你說,你的時間也在數據傳輸中丟失了。但請考慮不要在每個連接上創建新線程並使用線程池。

和薩拉姆。

+0

alaik o alsalam va rahmat allah!謝謝..我不認爲序列化可以真正影響連接(並且你沒有上帝爲像我這樣的懶惰人做序列化)).helpfull回答 – Sina 2012-07-31 06:55:46