2013-10-21 172 views
0


我在Java中編寫UDP服務器和客戶端以將消息從客戶端發送到服務器。在我的情況下,來自客戶端的每條消息都將存儲在數據庫中。我試圖使用固定線程池來創建多線程UDP服務器。但是現在我遇到了一個問題,我發現客戶端的一條消息可以被多個線程處理。我的服務器是這樣的:Java多線程UDP服務器錯誤

DatagramSocket serverSocket = new DatagramSocket(9876); 
    Map<String, Integer> retryMap = new ConcurrentHashMap<>(); 
    byte[] receiveData = new byte[1024]; 

    ExecutorService executor = Executors.newFixedThreadPool(2); 

    while(true){ 
     DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); 
     serverSocket.receive(receivePacket); 
     executor.execute(new ThreadServer(receivePacket, retryMap)); 
    } 

ThreadServer類:

public void run(){ 
    String temp = new String(packet.getData(), 0, packet.getLength()); 
    long threadId = Thread.currentThread().getId(); 
    System.out.println("Thread Id = "+threadId+" Message = "+temp); 
    // insert message to db 
} 

而且我的客戶是這樣的:

public class UDPClient1{ 
String message; 
public UDPClient1(String message){ 
    this.message = message; 
    try{ 
     byte[] sendData; 

     DatagramSocket clientSocket = new DatagramSocket(); 
     InetAddress IPAddress = InetAddress.getByName("localhost"); 

     sendData = message.getBytes("UTF-8"); 

     DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 9876); 
     clientSocket.send(sendPacket); 

     clientSocket.close(); 
    }catch(Exception e){ 
     e.printStackTrace(); 
    } 
} 

public static void main(String args[]) throws InterruptedException{ 
    int i = 0; 
    while(i < 1000){ 
     new UDPClient1("T000"+i+"_"+i); 
     System.out.println(i); 
     i++; 
     Thread.sleep(2); 
    } 
}} 

從服務器顯示輸出,有時從客戶端一個消息會由2個或更多線程處理。

Thread Id = 18 Routing Id = T000975 09:54:11,759 ERROR LogRoutingFileDaoImpl:59 - AMS - Error insert to database org.springframework.dao.DuplicateKeyException: PreparedStatementCallback; SQL [INSERT INTO LOG_ROUTING_FILE (ID_ROUTING_FILE, FILE_NM , PATH, TYPES, PROTOCOL, SOURCE_NM, TARGET_NM) VALUES (?,?,?,?,?,?,?)]; ERROR: duplicate key value violates unique constraint "log_routing_file_id_routing_file_key"; nested exception is org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "log_routing_file_id_routing_file_key" 
Thread Id = 9 Routing Id = T000975 09:54:11,759 ERROR LogRoutingFileDaoImpl:59 - AMS - Error insert to database org.springframework.dao.DuplicateKeyException: PreparedStatementCallback; SQL [INSERT INTO LOG_ROUTING_FILE (ID_ROUTING_FILE, FILE_NM , PATH, TYPES, PROTOCOL, SOURCE_NM, TARGET_NM) VALUES (?,?,?,?,?,?,?)]; ERROR: duplicate key value violates unique constraint "log_routing_file_id_routing_file_key"; nested exception is org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "log_routing_file_id_routing_file_key" 

T000975由螺紋9和18處理的消息..誰能幫我解決這個問題? :)

回答

2
byte[] receiveData = new byte[1024]; 

你分享在所有DatagramPackets.移動相同的字節數組接收環路內這條線。

+0

謝謝,它的工作:)你能否請解釋一下,將循環內外的recevieData聲明放置在循環之外有什麼區別? –

+0

我已經回答了。 '你在所有'DatagramPackets'中共享同一個字節數組。'如果你在循環中移動它,每個數據包都有一個新的字節數組。 – EJP

+0

非常感謝:D –