2011-09-14 11 views
1

私はTCPでデータを転送するのに問題がありました。だから、私はUDPサーバーを書いていたが、その動作していない、次のエラーを示して、どのように私はそれを修正することはできますか?JavaでUDPサーバーを修正するには?

マイエラー:

run: 
UDP Server started 
Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread 
    at java.lang.Thread.start0(Native Method) 
    at java.lang.Thread.start(Thread.java:657) 
    at socket.UDPHandler.start(UDPHandler.java:25) 
    at socket.UDPServer.waitForConnections(UDPServer.java:27) 
    at socket.UDPServer.main(UDPServer.java:46) 
BUILD STOPPED (total time: 14 seconds) 

UDPServer.java

package socket; 
import java.net.*; 
import java.io.*; 

public class UDPServer 
{ 
    private int serverPort = 0; 
    private DatagramSocket serverSock = null; 
    //private Socket sock = null; 

    public UDPServer(int serverPort) throws IOException 
    { 
     this.serverPort = serverPort; 
     serverSock = new DatagramSocket(serverPort); 
     System.out.println("UDP Server started"); 
    } 

    public void waitForConnections() 
    { 
     while (true) 
     { 
      try { 
       //sock = serverSock.accept(); 
       //System.err.println("Accepted new socket"); 
       UDPHandler handler = new UDPHandler(serverSock); 
       handler.start(); 
      } 
      catch (IOException e){ 
       e.printStackTrace(System.err); 
      } 
     } 
    } 

    public static void main(String argv[]) 
    { 
     int port = 8889; 

     UDPServer server = null; 
     try { 
      server = new UDPServer(port); 
     } 
     catch (IOException e){ 
      e.printStackTrace(System.err); 
     } 
     server.waitForConnections(); 
    } 

} 

UDPHandler.java

package socket; 
import java.io.*; 
import java.net.*; 
import main.*; 
public class UDPHandler implements Runnable 
{ 
    private DatagramSocket sock = null; 
    private DatagramPacket sockInput = null; 
    private DatagramPacket sockOutput = null; 
    private Thread myThread = null; 

    public UDPHandler(DatagramSocket sock) throws IOException 
    { 
     this.sock = sock; 
     //sockInput = new DatagramPacket(); 
     //sockOutput = sock.getOutputStream(); 
     this.myThread = new Thread(this); 
    } 

    public void start() 
    { 
     myThread.start(); 
    } 

    public void run() 
    { 
     while(true) 
     { 
      byte[] buf=new byte[1024]; 
      int bytes_read = 0; 
      try {         
       // Incoming - Test     
       sockInput = new DatagramPacket(buf, buf.length); 
       sock.receive(sockInput); 
       bytes_read = sockInput.getLength();     
       String data = new String(sockInput.getData()); 
       System.err.println("DATA: " + bytes_read + " bytes, data=" +data); 

       // IP - Test 
       InetAddress IPAddress = sockInput.getAddress(); 
       int port = sockInput.getPort(); 

       // Sending - Test 
       sockOutput = new DatagramPacket(data.getBytes(), data.length(), IPAddress, port); 
       sock.send(sockOutput); 

      } catch (Exception e) { 
       e.printStackTrace(System.err); 
       break; 
      } 
     } 

     try { 
      System.err.println("Closing socket."); 
      sock.close(); 
     } catch (Exception e) { 
      System.err.println("Exception while closing socket, e="+e); 
      e.printStackTrace(System.err); 
     } 

    } 

} 
+1

UDPは損失の多いプロトコルであり、パケットは失われ、断片化し、順序が乱れていることに留意する価値があります。ループバックではめったに発生しませんが、実際のネットワークではかなり頻繁に発生する可能性があります。 –

答えて

6

あなたは(しばらくのwaitForConnection中(真)ループをスレッドの無限の数を作成しています) 方法。サーバー内でDatagramSocket receive()メソッドを呼び出す必要があります(処理をブロックしています)。データグラムが受信された場合は、その処理を(たとえばスレッドプールから取得した)ハンドラに委譲してください。

+0

あなたはこれのような何かを意味する? '\\\\\\\ byte [] buf =新しいバイト[1024]; DatagramPacket rp =新しいDatagramPacket(buf、buf.length); serverSock.receive(rp); System.err.println(buf.length); System.exit(0); \\\\\ ' – YumYumYum

+0

ありがとうございます。これを加えて働いた。 * \\^nc -u localhost 8889 $ /将来の参照... '\\\ lsof -n -P -i:8889 ** – YumYumYum

0

私は/デバッグコードを実行しませんでしたが、java.lang.OutOfMemoryErrorは私がそれらのwhile(true)ループ内で起こって何かがあると思い、どちらかあまりにも多くのハンドラがwaitForConnections()(少ない)で作成されているか、あまりにも多くのバイト[]バッファがありますrun()(おそらく)に割り当てられます。

ポスターについては、while(true)ループの各行の最初の行にprintステートメントを追加して、実行された回数を確認してください。

リスニングUDPサーバーと単純なテストアプリケーションだけでJVMがメモリ不足になるのは奇妙なことです。私は誰かがそれにデバッグして確認することを願って、私は現時点でコードを実行することはできません。

1

receive()メソッドがメモリリークを引き起こすことがわかりました。 javaがUDPパケットを待つ間、他のスレッドが動作していないときはメモリ使用量がゆっくりと増加します。 .receive()メソッドの実行中に1時間に約20kbのメモリー使用量を増やしているようです。

その理由はわかりません。

関連する問題