I have a server which takes a request for a WSDL and sends back the WSDL's XML line by line. I know the request is being received and processed correctly because I have the server printing out the XML to the console as it's writing to the server socket. My problem right now is my client app is supposed to be reading in the xml and then printing out method signatures using the xml. I'm going to use DOM / DocumentBuilder to get the parts of the method signature(s) from the WSDL, but I need to first put the lines read in into a file. How can I do this? Currently I'm trying to do it this way:
//request WSDL from server
System.out.println("Client requesting \"MathServices?wsdl\"...");
socketWriter.write("GET MathServices?wsdl");
socketWriter.close();
//read XML response into file
try {
File wsdlXML = new File("MathServices.xml");
FileOutputStream wsdlXmlWriter = new FileOutputStream(wsdlXML);
String xmlLine;
while((xmlLine = socketReader.readLine()) != null){
wsdlXmlWriter.write(xmlLine.getBytes());
}
} catch (IOException e) {
e.printStackTrace();
}
But am getting this error:
Client requesting "MathServices?wsdl"...
java.net.SocketException: socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.readLine(BufferedReader.java:299)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
at client.Client.main(Client.java:50)
EDIT: server code
package server;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Scanner;
public class RequestHandler extends Thread {
Object block;
ServerSocket serverSocket;
BufferedReader socketReader;
PrintWriter socketWriter;
public RequestHandler(Object block, ServerSocket serverSocket){
this.block = block;
this.serverSocket = serverSocket;
}
#Override
public void run() {
try{
System.out.println("Waiting for connection...");
Socket clientSocket = serverSocket.accept();
System.out.println("Connection made.");
synchronized(block){
System.out.print("Notifying server thread...");
block.notify();
System.out.println("...done");
System.out.println();
}
System.out.println("Setting up streams...");
socketReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
socketWriter = new PrintWriter(clientSocket.getOutputStream(), true);
System.out.println("Reading request");
String input;
while((input = socketReader.readLine()) != "\n"){
//System.out.println("Input: " +input);
if(input.startsWith("GET")){
System.out.println("GET received.");
getResource(input);
}
}
socketWriter.close();
socketReader.close();
clientSocket.close();
System.out.println("Streams closed.");
}catch(IOException e){
System.out.println("IOException!");
e.printStackTrace();
}
}
public void getResource(String getRequest){
String[] parts = getRequest.split("\\s+");
String filename = parts[1].substring(1);
if(filename.equals("MathServices?wsdl")){
filename = "MathServices.wsdl";
}
System.out.println(filename);
File resource = new File(filename);
sendResponse(resource, 1);
}
public void sendResponse(File resource, int type){
System.out.println(resource.getAbsolutePath());
Scanner fileReader;
try {
fileReader = new Scanner(resource);
while(fileReader.hasNext()){
String line = fileReader.nextLine();
System.out.println(line);
socketWriter.println(line);
}
socketWriter.println("\n");
System.out.println("end of response");
socketWriter.close();
} catch (FileNotFoundException e) {
System.out.println("File not found!");
e.printStackTrace();
}
}
}
It looks like you are closing the Socket before reading from socketReader. You must fully read the results from that object before closing the Socket. Is this all of the code? You could also try adding socketWriter.flush() prior to closing it.
Edit:
I noticed that you are sending a GET request to the server, presumably intending to issue an HTTP GET? If so your request is malformed. Try this:
socketWriter.write("GET /MathServices?wsdl HTTP/1.1\r\n\r\n");
You would probably be better off using java.net.URLConnection or Apache HttpClient for this task.
Related
I am trying to build a simple request/response server.
Client send a message to Server. Then, the server response a message to client.
Server-side Code
package com.techoffice.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import javax.net.ServerSocketFactory;
public class TcpServerAppl {
static int port = 1010;
static ServerSocket serverSocket;
static {
try {
serverSocket = ServerSocketFactory.getDefault().createServerSocket(port);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
System.out.println("Server is running on " + port);
while(true){
Socket socket = null;
try{
socket = serverSocket.accept();
System.out.println("Someone is connecting to the server");
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
PrintWriter printWriter = new PrintWriter(os);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
// read message from client
String line = bufferedReader.readLine();
while(line != null && line.length() > 0){
System.out.println(line);
line = bufferedReader.readLine();
}
// reader.close();
// send message to client
System.out.println("Server starts sending message to client");
printWriter.println("This is a message sent from server");
printWriter.flush();
// printWriter.close();
} catch(Exception e){
System.err.println(e.getMessage());
} finally {
if (socket != null){
try {
socket.close();
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
}
}
}
}
Client-side code
package com.techoffice.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.net.SocketFactory;
public class TcpClientAppl {
public static void main(String[] args) throws UnknownHostException, IOException{
// start socket connection
Socket socket = SocketFactory.getDefault().createSocket("localhost", 1010);
PrintWriter printWriter = new PrintWriter(socket.getOutputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// send message to server
printWriter.println("Send Message From Client" );
printWriter.flush();
// printWriter.close();
// read message from server
System.out.println("Client starts reading from Server");
String line = bufferedReader.readLine();
while(line != null && line.length() > 0){
System.out.println(line);
line = bufferedReader.readLine();
}
// bufferedReader.close();
// close scoket connection
socket.close();
}
}
The Server is blocked at the Buffered Reader. However, if I tried to close the Buffered Reader by closing in Print Writer in Client, the Client throw an exception of "Connection Closed".
It is known that closing in PrintWriter or BufferedReader would close the socket connection.
Update
Specifying a End of Request/Message would be one of solution. But in this case, I would not want to have an End of Request. I just want to have response for a request no matter no many line is in the request.
The client throw an exception of 'connection closed'
No it doesn't. If you uncomment the printWriter.close() line it will throw an exception 'socket closed'.
But to your real problem. The server reads lines until end of stream before it sends anything: end of stream will never occur until the peer closes the connection; and the peer isn't closing the connection, except as above; so it will never send anything and just stay blocked in readLine(); so the client will block forever in readLine() too.
As this is evidently an echo server, it should echo every line as it is received.
Question is missing exception thrown by client side. Maybe try to close everything (reader,writer) on server-side after your communication is done. BTW. you don't need to call flush before calling close. Also you can use try-catch-withResources with socket on server side
This is the code for my server, its supposed to take an input from the user, print it into console, then send it back to the user.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class DateServer {
public static void main(String[] args) throws Exception {
ServerSocket listener = new ServerSocket(10219);
Socket s = listener.accept();
InputStreamReader in = new InputStreamReader(s.getInputStream());
BufferedReader input = new BufferedReader(in);
PrintWriter out = new PrintWriter(s.getOutputStream());
out.println("connected");
out.flush();
System.out.println("connected");
String test;
while (true) {
try {
test = input.readLine();
System.out.println(test);
out.println(test + " is what I recieved");
out.flush();
} catch(Exception X) {System.out.println(X);}
}
}
}
This is the code for the client:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.*;
public class DateClient {
public static Scanner keyboard = new Scanner(System.in);
public static void main(String[] args) throws Exception {
System.out.println("Enter IP Address of a machine that is");
System.out.println("running the date service on port 10219:");
String serverAddress = keyboard.next();
Socket s = new Socket(serverAddress, 10219);
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream());
System.out.println(input.readLine());
while(true){
try{
System.out.println(input.readLine());
out.println(keyboard.next());
out.flush();
} catch(Exception X){System.out.println(X);}
}
}
}
This was designed to work across a LAN network. I have no idea why it doesn't work, all that happens is the client will get the message "connected" and nothing else will happen, no matter what is typed into the client end. I'm a noob when it comes to java, but after a bunch of googling and searching through the java libraries, I can't seem to make it work. What did I do wrong?
You send one line from the server to the client, but in your client you wait for two lines before accepting user input to be sent to the server.
Bearing in mind that input.readLine() will block until data is received, can you spot the deadlock here:
Server:
out.println("connected");
while (true) {
try {
input.readLine();
}
}
Client:
input.readLine();
while(true) {
try {
input.readLine();
out.println(keyboard.next());
}
}
(extraneous code trimmed away to show just the problematic sequence of statements)
Both your client and server mutually wait for each other trying to do input.readLine().
This can be easily seen if you remove server's out.println("connected") and its corresponding client's first input.readLine().
On the client, you should probably write first and only then read the response. Try reordering the following lines:
System.out.println(input.readLine());
out.println(keyboard.next());
out.flush();
to get
out.println(keyboard.next());
out.flush();
System.out.println(input.readLine());
In the client, try changing
PrintWriter out = new PrintWriter(s.getOutputStream());
System.out.println(input.readLine());
while(true){
try{
System.out.println(input.readLine());
out.println(keyboard.next());
out.flush();
} catch(Exception X){System.out.println(X);}
}
to
PrintWriter out = new PrintWriter(s.getOutputStream());
while(true){
try{
System.out.println(input.readLine());
out.println(keyboard.nextLine());
out.flush();
} catch(Exception X){System.out.println(X);}
}
Your client is trying to read two lines, but your server sends just one, then polls for input, so both are locked. Also, sinc your server is reading line-by-line, your client should be sending data line-by-line.
I am new to java and network programming for the most part. I want to write a program that automatically backs up my texts to my computer whenever my phone connects to my home wifi.
I am working on creating java classes that will handle sending data over the network. Using some questions found here, I came up with this implementation but I have some questions regarding some of the methods used in what I learned from.
Two Questions Regarding this code
I totally used a question from SO for the send methods in my client. The sendText uses a new thread, but the sendFile doesn't. Any particular reason why?
2. At which point in the code does the server actually know when there has been a message sent to the port? Is it at the method accept() call or is it when the BufferStream readLine() is checked? Does accept just grab data and throw it into the buffer? null implying the data grabbed was not a signal sent from a client?
Does the accept() method block execution of the code until a connection attempt is made from a client?
Thanks!
KServ
//Used to launch the server
public class KServ {
public static void main(String[] args) {
if (args.length != 1) {
System.err.println("Usage: java KServ <port number>");
System.exit(1);
}
int port = Integer.parseInt(args[0]);
KServer server = new KServer(port);
while (true) { //added this to keep the server polling for new data
server.run();
}
}
}
KServer
//Server class. Should handle data incoming
import java.net.*;
import java.io.*;
public class KServer {
private int port;
public KServer(int PORT) {
port = PORT;
}
public void run() {
try (
ServerSocket sSocket = new ServerSocket(port);
Socket cSocket = sSocket.accept();
PrintWriter out = new PrintWriter(cSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(cSocket.getInputStream()));
) {
String input;
while ((input = in.readLine()) != null) {
System.out.println(input);
}
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port " + port + " or listening for a connection");
System.out.println(e.getMessage());
}
}
}
Client
//launches KClient object and uses it to send input from console to the server
import java.util.Scanner;
public class Client {
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("Usage: java Client <ip number> <port number>");
System.exit(1);
}
String ip = args[0];
int port = Integer.parseInt(args[1]);
KClient client = new KClient(ip,port);
String msg;
Scanner inStream = new Scanner(System.in);
while((msg = inStream.nextLine()).length() > 0) {
client.sendText(msg);
}
}
}
KClient
//Will be used to establish connection with server and send data from phone
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class KClient {
private String server;
private int port;
public KClient(String Server,int Port) {
server = Server;
port = Port;
}
public void sendFile(String fileName) {
File file = new File(fileName);
FileInputStream fileInputStream;
BufferedInputStream bufferedInputStream;
OutputStream outputStream;
try {
client = new Socket(server,port);
byte[] bytes = new byte[(int) file.length()];
fileInputStream = new FileInputStream(file);
bufferedInputStream = new BufferedInputStream(fileInputStream);
bufferedInputStream.read(bytes, 0, bytes.length);
outputStream = client.getOutputStream();
outputStream.write(bytes,0,bytes.length);
outputStream.flush();
bufferedInputStream.close();
outputStream.close();
client.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private Socket client;
private OutputStreamWriter outputStreamWriter;
public void sendText(String msg) {
System.out.println("Send Message!");
new Thread(new Runnable() {
#Override
public void run() {
try {
client = new Socket(server,port);
outputStreamWriter = new OutputStreamWriter(client.getOutputStream(), "ISO-8859-1");
outputStreamWriter.write(msg);
outputStreamWriter.flush();
outputStreamWriter.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
BufferedReader inStream;
public boolean Shake() {
try {
client = new Socket(server,port);
inStream = new BufferedReader(new InputStreamReader(client.getInputStream()));
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
}
I totally used a question from SO for the send methods in my client. The sendText uses a new thread, but the sendFile doesn't. Any particular reason why?
Unanswerable. Ask the author. Both sends can block. As the file is presumably longer than the text, it would have made more sense to do it the other way round.
2. At which point in the code does the server actually know when there has been a message sent to the port? Is it at the method accept() call
No.
or is it when the BufferStream readLine() is checked?
Yes.
Does accept just grab data and throw it into the buffer?
No. It grabs a connection and returns it as a socket. Nothing to do with data whatsoever.
null implying the data grabbed was not a signal sent from a client?
You seem to be actually asking about BufferedReader.readLine() here, not ServerSocket.accept(), which doesn't return null. readLine() returns null when there is no pending data to be read and the peer has closed the connection.
Does the accept() method block execution of the code until a connection attempt is made from a client?
More or less. It blocks until there is a complete connection waiting to be accepted, which isn't quite the same thing, as there is a queue.
I will add that you have copied, or written, some truly terrible code here. There are much better examples.
I don't know this is possible or not.First I wrote client and server in Node.js and then both server and client wrote in Java those were worked as expected. Now I'm interested in connect Java server and Node.js client. But problem is cant send date between them
This is server side code which is written in Java
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class MyServer {
public MyServer() {
}
public static void main(String args[]){
ServerSocket serverSocket= null;
Socket socket =null;
DataInputStream datainputstream=null;
DataOutputStream dataoutputstream=null;
try{
serverSocket = new ServerSocket(8888);
System.out.println("Listening ...");
}catch(IOException e){
e.printStackTrace();
}
while(true){
try{
socket = serverSocket.accept();
datainputstream = new DataInputStream(socket.getInputStream());
dataoutputstream = new DataOutputStream(socket.getOutputStream());
System.out.println("ip:"+socket.getInetAddress());
System.out.println("message:"+datainputstream.readUTF());
dataoutputstream.writeUTF("HELLO !");
}catch(IOException e){
e.printStackTrace();
}finally{
if(socket!=null){
try{
socket.close();
}catch(IOException e){
e.printStackTrace();
}
}
if(datainputstream!=null){
try{
datainputstream.close();
}catch(IOException e){
e.printStackTrace();
}
}
if(dataoutputstream !=null){
try{
dataoutputstream.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
}
}
}
This is client side code which is written in Node.js
var net = require('net');
var HOST = '127.0.0.1';
var PORT = 8888;
var client = new net.Socket();
client.connect(PORT, HOST, function() {
console.log('connected to: ' + HOST + ':' + PORT);
client.write('Data comming from client...');
});
client.on('data', function(data) {
console.log(data.toString());
//client.destroy();
});
client.on('close', function() {
console.log('Connection closed');
});
Your server (Java) is expecting a message from the client before it sends anything. It will block until it receives such a message. Since the server seems to not receive this message, either the client is not actually sending its message (ie, it's queueing it until it receives more data to send), or the server is expecting to receive more data.
The documentation for DataInputStream.readUTF() claims that it expects length-prefixed strings. That's not what your client is writing. The server is probably interpreting the first two bytes of your string as a length, then trying to read that many bytes of data, Since there isn't that much data available, it's going to wait for more from the client. Try using BufferedReader.readLine() instead, and make sure that your client is sending a newline at the end of its output.
If that doesn't work, try finding a way to flush the socket on the client side. I don't know Node.js, but a quick skim of the documentation suggests that socket.end() might help, although that won't work if you need to send more data later on.
Here is the solution for this
Server side code
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.BufferedInputStream;
import java.io.*;
public class MyServer {
public MyServer() {
}
public static void main(String args[]){
ServerSocket serverSocket= null;
Socket socket =null;
BufferedReader datainputstream=null;
try{
serverSocket = new ServerSocket(8888);
System.out.println("Listening ...");
}catch(IOException e){
e.printStackTrace();
}
try{
socket = serverSocket.accept();
}catch(IOException e){
System.out.println("can't listen given port \n");
System.exit(-1);
}
try{
datainputstream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("ip:"+socket.getInetAddress());
}catch(IOException e){
System.out.println("can't read File \n");
System.exit(-1);
}
try{
StringBuilder sb = new StringBuilder();
String line = null;
while((line=datainputstream.readLine())!=null){
sb.append(line+"\n");
}
datainputstream.close();
System.out.println("message:"+sb.toString());
}catch(IOException e){
System.out.println("Cant read file \n");
}finally{
if(socket!=null){
try{
socket.close();
}catch(IOException e){
e.printStackTrace();
}
}
if(datainputstream!=null){
try{
datainputstream.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
}
}
here is the my client
Client side code
var net = require('net');
var client = net.connect(8888, 'localhost');
client.write('Hello from node.js');
client.end();
Server and client communicating with my own protocol which looks like XMPP. I should to realize chat application. So when one user write String it immedeatly should be sended to other client through the server. I have method sendToAll on server. But user see the message of other user only when it press enter.
How can user receive messages without pressing enter button?
So this is my client:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import org.apache.log4j.Logger;
import dataart.practice.protocols.XMLProtocol;
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);
private static BufferedReader in;
private static PrintWriter out;
private static BufferedReader inu;
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);
in = new BufferedReader(new InputStreamReader(fromserver.getInputStream()));
out = new PrintWriter(fromserver.getOutputStream(), true);
inu = new BufferedReader(new InputStreamReader(System.in));
String fuser, fserver;
while (true){
if(in.ready()){//fserver = in.readLine()) != null) {
System.out.println("asdasdsd");
fuser = inu.readLine();
if (fuser != null) {
if (fuser.equalsIgnoreCase("close"))
break;
if (fuser.equalsIgnoreCase("exit"))
break;
protocol.setComId((long) 0);
protocol.setContent(fuser);
protocol.setLogin("Guest");
try {
JAXBContext jaxbContext = JAXBContext.newInstance(XMLProtocol.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, false);
jaxbMarshaller.marshal(protocol, out);
out.flush();
} catch (JAXBException e) {
LOG.error("Error while processing protocol" + e);
}
}
}
}
out.close();
in.close();
inu.close();
fromserver.close();
}
}
And Server with ServerThread.
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);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
userCounter++;
addUser("Guest" + userCounter, out);
LOG.trace("User " + userCounter + " has been added!");
exec.execute(new ServerThread(socket, in, out));
} catch (IOException e) {
socket.close();
}
}
} finally {
s.close();
}
}
ServerThread.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.net.Socket;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import org.apache.log4j.Logger;
import dataart.practice.protocols.XMLProtocol;
import dataart.practice.serverUtils.Commands;
public class ServerThread implements Runnable {
private static final Logger LOG = Logger.getLogger(ServerThread.class);
private XMLProtocol protocol;
private Socket socket;
private BufferedReader in;
private PrintWriter out;
private String buffer = "";// may be exist another. way but it's not working
private Boolean login = false;
public ServerThread(Socket s, BufferedReader in, PrintWriter out) throws IOException {
this.in = in;
this.out = out;
out.println("</XMLProtocol>");
socket = s;
new Thread(this);
}
public void run() {
try {
while (true) {
if ((buffer = in.readLine()) != null) {
if (buffer.endsWith("</XMLProtocol>")) {
protocol = getProtocol(buffer);
//Server.onlineUserList.put(protocol.getLogin(), out);
/* if (!login){
out.println("Maybe login first?");
}
*/
LOG.trace("Getting message from user: " + protocol.getLogin() + " recived message: " + protocol.getContent());
///out.println(protocol.getLogin() + " says:" + protocol.getContent());
Server.sendToAll(protocol.getContent()+"</XMLProtocol>");
} else {
LOG.trace("Nop protocol do not send with it end");
}
}
}
} catch (IOException e) {
LOG.error("Error in reading from stream: " + e);
} catch (JAXBException e) {
LOG.error("Error in Marshalling: " + e);
} finally {
try {
socket.close();
LOG.trace("Socket closed");
} catch (IOException e) {
LOG.error("Socket no closed" + e);
}
}
}
public XMLProtocol getProtocol(String buffer) throws JAXBException {
JAXBContext jaxbContext = JAXBContext.newInstance(XMLProtocol.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
return (XMLProtocol) jaxbUnmarshaller.unmarshal(new StreamSource(new StringReader(buffer)));
}
public Boolean loginIn(XMLProtocol protocol) {
return true;
}
}
You will need to multi-thread both the client and server. The client will need one thread that listens for messages from the server and writes them to his/her screen and one thread that waits for his/her keyboard input and sends it to the server. Likewise for each connection to the server, it will need a thread waiting for input from the client and one thread sending output from other users to the client.
The reason you don't see incoming messages until you press enter is because of the client while loop. It's commented out now, but it looks like your loop used to:
- Read incoming messages from server
- Read input from keyboard
- Send input to server
So you read whatever was available from the server, and then the client waits for more keyboard input before reading from the server again (in the next iteration).
Another word of advice, from my understanding, creating JAXBContext can be an expensive operation. You don't need to recreate it every time you send a message. Consider initializing one in your server and client and then reusing it for each marshall/unmarshall.
Try this,
Do Not use BufferedReader() with PrintWriter..... PrintWriter is itself the Bridge between byte level socket data and character form.
Eg:
I am showing for a single client, use the while loop for n nos of clients
ServerSocket s = new ServerSocket(4444);
Socket incoming = s.accept();
OutputStream output = s.getOutputStream();
PrintWriter pw = new PrintWriter(output,true);
System.out.println(pw.write(new Scanner(System.in).nextLine()));