2011-09-14 2 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 날 중 하나 너무 많은 핸들러 waitForConnections() (덜) 또는 너무 많은 바이트 [] 버퍼가에서 생성되고, 그 while(true) 루프 내부에서 무슨 일이 있다고 생각합니다 run() (더 있음)에 할당됩니다.

포스터의 경우 print 명령문을 실행 횟수만큼 보려면 while(true) 루프의 첫 줄에 추가하십시오.

청취 UDP 서버 및 간단한 테스트 응용 프로그램 만 있으면 JVM이 메모리가 부족한 것처럼 보입니다. 누군가가 디버깅하여 확인할 수 있기를 바랍니다. 지금은 코드를 실행할 수 없습니다.

1

receive() 메서드가 메모리 누수를 일으킨다는 것을 알게되었습니다. java가 UDP 패킷을 기다리는 동안 다른 스레드가 작동하지 않을 때 메모리 사용이 서서히 증가합니다. .receive() 메소드를 실행하는 동안 시간당 약 20kb의 메모리 사용량을 증가시키고있는 것으로 보입니다.

이유가 확실하지 않습니다.

관련 문제