2012-07-29 35 views
1

我有一個從LIS機器讀取和寫入數據的程序。我正在從特定端口讀取數據並將數據寫入數據庫表。當我從表中讀取數據並將其添加到Arraylist中時,它將添加重複記錄。我找不到解決方案。如何在多線程套接字連接中實現讀寫方法

的代碼如下:

public class PacsMultiThread extends Thread{ 

    private static Logger logger = Logger.getLogger(PacsMultiThread.class); 

    // instance for Server socket and Socket class 
    private ServerSocket serverSocket = null; 
    private Socket socket = null; 
    ServerParams params = Configuration.getConfig().getServerParams(); 

    PacsMultiThread() { 

     super("PacsMultiThread"); 

     try { 
      // listen on local port 
      serverSocket = new ServerSocket(Configuration.getConfig().getHostParams().getPort()); 

     } catch (IOException e) { 
      logger.error("Could not listen on port: " + Configuration.getConfig().getServerParams().getPort() + ", " + e); 
      System.exit(1); 
     } 
    } 

    /* 
    * thread run method call 
    * @see java.lang.Thread#run() 
    * Mohammod Hossain 
    */ 
    public void run() { 

     logger.info("run method is calling... "); 

      if (serverSocket == null) 
       return; 

      while (true) {    
       try { 
        socket = serverSocket.accept(); 
        logger.info("connection status: "+ socket.isConnected()); 
       } catch (IOException e) { 
        logger.error("Accept failed: " + Configuration.getConfig().getServerParams().getPort() + ", " + e); 
        System.exit(1); 
       }   

        try { 
         // readData(); 
         //calling new Thread for reading data from port 
         ReadHandler readThread = new ReadHandler(socket); 
         readThread.start(); 

         // writeData(socket); 

         //calling new Thread for writing data into port 
         WriteHandler writeThread = new WriteHandler(socket); 
         writeThread.start(); 

         } catch (Exception e) { 
          logger.error(e.getMessage()); 
         }   
      } 
     } 




    public class WriteHandler extends Thread { 
     private static Logger logger = Logger.getLogger(WriteHandler.class); 
     private Socket socket; 

    ServerParams params = Configuration.getConfig().getServerParams(); 
    OutputStream out = null; 

    public WriteHandler(Socket socketConnection){ 
     super(); 
     this.socket = socketConnection; 
    } 

    @Override 
    public void run() { 

     writeData(socket); 
    } 

    private void writeData(Socket socket){ 

     /* 
      * calling writeData method for data write to port 
      * @param Socket socket 
      */ 

     logger.info("writeData method is called :: ");  

      try{ 
       //calling client socket method for connect to server port 
      // logger.info(" client socket "+socket.getRemoteSocketAddress()); 
       // check data exist in table in HL7001; 

       List<HL7001> orderList = new ArrayList<HL7001>(); 
       PacsDao pacsDao = new PacsDao(); 
       orderList = pacsDao.getAllOrder();    

       //PrintWriter pw = new PrintWriter(theOutput, false); 
       int msgCount = 0; 

       if(orderList.size() > 0){ 

        for(int i = 0;i<orderList.size();i++){ 

        logger.info("orderList.size(): " + orderList.size()); 

        HL7001 model = orderList.get(i); 

        logger.info("message from HL7001 Table :: " +"Msg Order No: "+ 
          model.getOrderNo() +"\n"+" msg no:"+ model.getHl7MsgNo()+"\n"+" message: "+model.getHl7Msg()); 


        //for(HL7001 model:orderList){     
        String tableMessage = model.getHl7Msg(); 

        // read ADT Message from Table HL7001; 

        //readADTMsg(tableMessage); 

        // logging TABLE MESSAGE data into file 


         StringBuffer transmitMsg = new StringBuffer(); 
         transmitMsg 
         .append(START_OF_BLOCK) 
         .append(tableMessage) 
         .append(END_OF_BLOCK) 
         .append(CARRAIGE_RETURN); 

         // write data to port 

         socket = new Socket(Configuration.getConfig().getServerParams().getUrl(), Configuration.getConfig().getServerParams().getPort()); 

         if(socket.isConnected()){ 
          logger.info(socket.getRemoteSocketAddress()+" port is connected "); 
          HL7007 hl7007 = new HL7007(); 
          hl7007.setMsgNo(model.getHl7MsgNo()); 
          hl7007.setPortAdress(socket.getRemoteSocketAddress().toString()); 
          opeonSocketLog(hl7007); 
         }else{ 
          logger.error("Server socket is not conneted"); 
         } 
         out = socket.getOutputStream(); 
         //InputStream in = socket.getInputStream(); 
         out.write(transmitMsg.toString().getBytes()); 

         // save file into directory    

         // logging TABLE MESSAGE data into file 
         if (params.isOutputOnFile()) { 
          //comment this line for performance issue 

          FileLogger.log2(transmitMsg.toString()); 
         } 

         /** Write across the socket connection and flush the buffer */ 

         out.flush();            
         out.close();       
         // insert into record from Table HL7001 to Table HL7003; 


         insertOrderModel(model);       

         msgCount++; 

         logger.info("msgCount "+ msgCount);      

         if (Configuration.getConfig().getServerParams().getWaitingOption().equals("1")) { 
          try{ 
           Thread.sleep(1000);        

          }catch (InterruptedException e) { 
           logger.error("Wait for writing message into "+ e.getMessage()); 
          } 
         }   
       }    

        }   

      }catch (Exception e) { 
       logger.error(e.getMessage()); 
       e.printStackTrace(); 
      }finally{ 
       try { 
        logger.info("finally block is executed in write method "); 
        socket.close(); 
       } catch (Exception e) { 
        logger.error(e.getMessage()); 
        e.printStackTrace(); 
       } 
      } 
    } 

在上述寫入類在第一I從表中讀出的記錄,然後添加到列表中。如果記錄存在,我打開套接字連接,然後將數據寫入端口並刪除以下記錄。但有時我得到更多的重複記錄

+0

當StringBuilder更合適時,不要使用StringBuffer。 – 2012-07-29 10:03:40

回答

2

這一切都發生兩次。你爲自己打開一個套接字(爲什麼?),所以另外一對讀寫器&創建,所以...你不應該通過TCP/IP與你自己溝通:在這一點上你的設計存在嚴重問題。

+0

我正在使用不同的端口進行讀寫4444和4445等不同的線程類讀取和寫入 – 2012-07-29 06:59:47

+1

您只需要一個服務器端口和一個用於讀寫的套接字。 – 2012-07-29 10:01:43

+1

@MohammodHossain對於每個套接字,您都有一個寫入線程正在創建與您自己創建寫入線程的連接。我很驚訝這不會很快炸燬。更新 - 我可以看到你在線之間睡了1秒。 :P – 2012-07-29 10:05:39

2

您不需要每個條目的套接字。

使用您接受的一個套接字,將所有內容發送到該套接字,並在完成時關閉它。

+0

請舉一個例子 – 2012-07-29 10:09:57

+0

這個例子就像你的代碼,但沒有創建新的套接字。 (正如EJP建議的那樣) – 2012-07-29 10:12:30

+0

我正在從一個端口讀取數據,但是寫入不同的端口,例如讀取端口4444和寫入端口4445 – 2012-07-30 04:34:34