2013-10-21 170 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 –