私はソケットでクライアント/サーバー アプリケーションをコーディングしており、独自のプロトコルを設計する必要があります。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 を解析しようとしています。
Edit my question:
今では例外が表示されます。marshall パラメータを変更します。
DefaultValidationEventHandler: [FATAL_ERROR]: 要素タイプ「xmlProtent」の後には、属性指定「>」または「/>」が続く必要があります。場所: 2 行目 javax.xml.bind.UnmarshalException: プロローグではコンテンツは許可されていません。- リンクされた例外あり: [org.xml.sax.SAXParseException; 行番号: 1; 列番号: 1; プロローグではコンテンツは許可されていません。] DefaultValidationEventHandler: [FATAL_ERROR]: プロローグではコンテンツは許可されていません。場所: com.sun.xml.bind.v2.runtime.SAXUnmarshallerHandlerImpl.handleEvent(SAXUnmarshallerHandlerImpl.java:870) の 1 行目 com.sun.xml.bind.v2.runtime.ErrorHandlerAdaptor.propagateEvent(ErrorHandlerAdaptor.java:82) でcom.sun.xml.bind.v2.runtime.ErrorHandlerAdaptor.fatalError(ErrorHandlerAdaptor.java: AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:214) at dataart.practice.server.ServerThread.run(ServerThread.java:41) 原因: org.xml.sax.SAXParseException; 行番号: 1; 列番号: 1; コンテンツはプロローグで許可されていません。com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:198) で com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:177) で... 16 さらに javax.xml.bind.UnmarshalException: 要素タイプ "xmlProtent" の後には、属性指定 ">" または "/>" が続く必要があります。- リンクされた例外あり: [org.xml.sax.SAXParseException; 行番号: 2; 列番号: 12; エレメントタイプ「xmlProtent」160) javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157)で javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:214)で dataart.practice.server.ServerThread.run (ServerThread.java:41) で java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) で java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) で java.lang.Thread で。 run(Thread.java:722) 原因: org.xml.sax.SAXParseException; 行番号: 2; 列番号: 12; 要素タイプ「xmlProtent」の後には、属性指定「>」または「/>」が続く必要があります。com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.