2012-06-08 162 views
0

我在套接字上編寫客戶端 - 服務器應用程序,我有任務來設計我自己的協議。客戶端和服務器與xml進行通信。我使用JAXB庫。客戶端將XML完美地寫入輸出流。但我無法在服務器中讀取它。你能展示如何正確地從客戶端接收數據嗎?客戶端服務器,設計協議

這是一個Client

public class Client { 
    public static final String SERVER_HOST = "localhost"; 
    public static final Integer SERVER_PORT = 4444; 
    public static final Logger LOG = Logger.getLogger(Client.class); 

    public static void main(String[] args) throws IOException { 

     System.out.println("Welcome to Client side"); 
     XMLProtocol protocol = new XMLProtocol(); 
     Socket fromserver = null; 

     fromserver = new Socket(SERVER_HOST, SERVER_PORT); 

     BufferedReader in = new BufferedReader(new InputStreamReader(fromserver.getInputStream())); 

     PrintWriter out = new PrintWriter(fromserver.getOutputStream(), true); 

     BufferedReader inu = new BufferedReader(new InputStreamReader(System.in)); 

     String fuser, fserver; 

     while ((fuser = inu.readLine()) != null) { 

      protocol.setComId((long) 0); 
      protocol.setContent("Client content"); 
      protocol.setLogin("User"); 

      try { 

       JAXBContext jaxbContext = JAXBContext.newInstance(XMLProtocol.class); 
       Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); 
       jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
       jaxbMarshaller.marshal(protocol, out); 

      } catch (JAXBException e) { 
       LOG.error("Error while processing protocol"+e);    
      } 

      fserver = in.readLine(); 

      System.out.println(fserver); 

      if (fuser.equalsIgnoreCase("close")) 
       break; 
      if (fuser.equalsIgnoreCase("exit")) 
       break; 
     } 

     out.close(); 
     in.close(); 
     inu.close(); 
     fromserver.close(); 
    } 

} 

而且服務器:

package dataart.practice.server; 

import java.io.IOException; 
import java.net.ServerSocket; 
import java.net.Socket; 

import org.apache.log4j.Logger; 

public class Server { 

    public static final Logger LOG = Logger.getLogger(Server.class); 
    public static final String SERVER_HOST = "localhost"; 
    public static final Integer SERVER_PORT = 4444; 
    public static Integer userCount = 0; 

    public static void main(String[] args) throws IOException { 

     LOG.trace("Server started"); 
     ServerSocket s = new ServerSocket(SERVER_PORT); 

     try { 
      while (true) { 
       LOG.trace("Waiting for connections..."); 
       Socket socket = s.accept(); 

       try { 
        new ServerThread(socket); 
        LOG.trace("Users in the chat: "+(userCount+1)); 
        userCount++; 

       } catch (IOException e) { 
        socket.close(); 
       } 
      } 
     } finally { 
      s.close(); 
     } 
    } 
} 

而且我的線程。

public class ServerThread extends Thread { 
    private static final Logger LOG = Logger.getLogger(ServerThread.class); 
    private Socket socket; 
    private BufferedReader in; 
    private PrintWriter out; 
    private String buffer; 
     public ServerThread(Socket s) throws IOException { 
     socket = s; 
     in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true); 
     start(); 
    } 

    public void run() { 
     try { 
      while (true) { 

      // if ((buffer = in.readLine()).endsWith("</xmlProtocol>")) { 
        JAXBContext jaxbContext = JAXBContext.newInstance(XMLProtocol.class); 
        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); 
        sXMLProtocol protocol = (XMLProtocol) jaxbUnmarshaller.unmarshal(in); 
        LOG.trace("Getting message from user" + protocol.getContent()); 
       } 
       LOG.trace("Nop"); 
      } 
     } catch (JAXBException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 

      e.printStackTrace(); 
     } finally { 
      try { 
       socket.close(); 
       LOG.trace("Socket closed"); 
      } catch (IOException e) { 
       LOG.error("Socket no closed" + e); 
      } 
     } 
    } 
} 

我應該在服務器上編寫什麼來解析我得到的XML?我嘗試解析InputStream。

​​現在它告訴我例外。我改變marshall參數。

DefaultValidationEventHandler:[FATAL_ERROR]:元素類型「xmlProtent」必須後面跟有屬性規範,「>」或「/>」。 位置:第2行 javax.xml.bind.UnmarshalException:prolog中不允許使用內容。 - 帶有鏈接的異常: [org.xml.sax.SAXParseException; lineNumber:1; columnNumber:1;內容在序言中是不允許的。] DefaultValidationEventHandler:[FATAL_ERROR]:內容在prolog中是不允許的。 位置:第1行 在com.sun.xml.bind.v2.runtime.SAXUnmarshallerHandlerImpl.handleEvent(SAXUnmarshallerHandlerImpl.java:870) 在com.sun.xml.bind.v2.runtime.ErrorHandlerAdaptor.propagateEvent(ErrorHandlerAdaptor.java :82) at com.sun.xml.bind.v2.runtime.ErrorHandlerAdaptor.fatalError(ErrorHandlerAdaptor.java:58) at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java :180) at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:441) at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter .java:368) at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1375) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl $ PrologDriver.next(XMLDocumentScannerImpl.java:996) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl。 java:607) at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:116) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument( XMLDocumentFragmentScannerImpl.java:488) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:835) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration。解析(XML11Configuration.java:764) at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:123) at com.sun.o rg.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1210) at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl $ JAXPSAXParser.parse(SAXParserImpl.java:568) at com.sun.xml.bind.v2.runtime.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:160) at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157) at javax.xml.bind。 helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl。java:214) at dataart.practice.server.ServerThread.run(ServerThread.java:41) 引起:org.xml.sax.SAXParseException; lineNumber:1; columnNumber:1;序言中不能有內容。 at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:198) at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java: 177) ... 16更多 javax.xml.bind.UnmarshalException:元素類型「xmlProtent」必須後跟任一屬性規範,「>」或「/>」。 - 帶有鏈接的異常: [org.xml.sax.SAXParseException; lineNumber:2; columnNumber:12;元素類型「xmlProtent」必須後跟任一屬性規範,「>」或「/>」。] at com.sun.xml.bind.v2.runtime.SAXUnmarshallerHandlerImpl.handleEvent(SAXUnmarshallerHandlerImpl.java:870) at com .sun.xml.bind.v2.runtime.ErrorHandlerAdaptor.propagateEvent(ErrorHandlerAdaptor.java:82) at com.sun.xml.bind.v2.runtime.ErrorHandlerAdaptor.fatalError(ErrorHandlerAdaptor.java:58) at com.sun .org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:180) at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:441) at com .sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:368) at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XML Scanner.java:1375) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.seekCloseOfStartTag(XMLDocumentFragmentScannerImpl.java:1354) at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl。 scanStartElement(XMLNSDocumentScannerImpl.java:245) at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl $ NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:602) at com.sun.org.apache.xerces.internal。 impl.XMLDocumentFragmentScannerImpl $ FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3063) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl $ PrologDriver.next(XMLDocumentScannerImpl.java:881) at com.sun.org。 apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:607) 在com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:116) 在com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java: 488) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:835) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration。 java:764) at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:123) at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse( AbstractSAXParser.java:1210) at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl $ JAXPSAXParser.parse(SAXParserImpl.java:568) at com.sun.xml.bind.v2.runti me.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:160) 在javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157) 在javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java: 214) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) at java.util.concurrent.ThreadPoolExecutor $ Worker。運行(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:722) 原因:org.xml.sax.SAXParseException; lineNumber:2; columnNumber:12;元素類型「xmlProtent」必須後跟屬性規範,「>」或「/>」。 at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper。Java的:198) 在com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:177) ...... 23多個

+1

你肯定沒有數據由服務器讀取或僅這一點,如果塊? – UVM

+0

服務器讀取數據,但它只讀取像這樣的字符串,而不是其他字段等。但我只想讀取一次緩衝區。 –

回答

0

你試圖調試的訂單

(buffer = in.readLine()).endsWith("</xmlProtocol>") 

也許它的結果是假

+0

沒有閱讀。服務器讀取所有客戶端發送給它的信息。但我不想讀Strings。我認爲這是一個關於JAXB功能的問題。 –

+0

我想我找到了; 你叫 sXMLProtocol協議=(XMLProtocol)jaxbUnmarshaller.unmarshal(); 沒有流解組 – duffy356

+0

我活得很清楚,因爲我真的不知道該寫什麼。如果我寫「在」那裏,像inputStream它不起作用。 –