socket closed exception occurs in an infinite loop - java

I'm supposed to write a program that take some .class files as service and they should be loaded and do the service. I'm have done it using socket programming but since I have made it multi-threaded so services can be used by any number of clients, i'm getting socket closed exception which occurs in an infinite while loop after each client thread is done. Even with one client i still get this exception. the only time that i do not get exception is when there is no class to load which i use break. I've tried to find the problem and searched a lot but I couldn't find anything.
//this is main class for server side
package reg.main;
import java.net.*;
import java.io.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.concurrent.*;
public class Application{
private final static Logger LOGGER = LoggerFactory.getLogger(Application.class);
public static void main(String[] args){
while(true){
InputStream input = null;
Properties prop = new Properties();
try{
String filename = "config.properties";
input = Application.class.getClassLoader().getResourceAsStream(filename);
if(input == null){
System.out.println("Sorry, unable to find " + filename);
}
prop.load(input);
}
catch(IOException ex){
System.out.println("properties file does not exist.");
}
try{
String port = prop.getProperty("port");
int portNo = Integer.parseInt(port);
ServerSocket serverSocket = new ServerSocket(portNo);
LOGGER.debug("Server is listening... on port " + portNo);
ExecutorService service = Executors.newFixedThreadPool(1);
service.execute(new Server(serverSocket.accept()));
serverSocket.close();
service.shutdown();
}catch (IOException e) {
System.out.println("Could not close socket");
System.exit(1);
}
}
}
}
// this is server side code
package reg.main;
import java.net.*;
import java.io.*;
import reg.entity.*;
import reg.utility.*;
import reg.service.*;
import reg.dao.*;
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Server implements Runnable{
private static final Logger LOGGER = LoggerFactory.getLogger(Server.class);
private Socket clientSocket;
public Server(Socket clientSocket){
LOGGER.debug("Connection is Established.");
this.clientSocket = clientSocket;
}
public void run(){
ObjectOutputStream outToClient = null;
ObjectInputStream inFromClient = null;
try{
outToClient = new ObjectOutputStream(clientSocket.getOutputStream());
inFromClient = new ObjectInputStream(clientSocket.getInputStream());
}
catch(IOException ex){
LOGGER.error("There is a problem in reading or writing.");
}
while(true){
try{
String userOption =(String)inFromClient.readObject();//while printing stack trace, it says there is something wrong with this line. i don't know why!
System.out.println(userOption);
userOption = DataEditor.editOptionInputInfo(userOption); //this is a custom method
Map<String,Service> mapper= CustomClassLoader.loadClass(); //in class loader .class files will be loaded and an object of each of them will be sent in a map
if(mapper == null){
LOGGER.debug("no class file found to be loaded.");
clientSocket.close();
break;
}
List<String> classNames = CustomClassLoader.getClassNames();
boolean ckeckedUserOption = Validation.validUserOption(classNames,userOption);
if(ckeckedUserOption == false){
LOGGER.error("client has entered the wrong option.");
}
System.out.println(userOption + "in server class------------- before loading class");
Service service = mapper.get(userOption);
List<String> parameters = service.getRequiredParameters();
if(parameters.size() == 0){
LOGGER.debug("There is a problem with loaded classes.");
}
outToClient.writeObject(parameters);
LOGGER.debug("required parameters was sent to client.");
List<String>info = (List<String>)inFromClient.readObject();
LOGGER.debug("Information from client has been sent.");
if(info.size() == 0){
LOGGER.error("client has not put information. Try again.");
System.exit(2);
}
String result = service.doOperation(info);
outToClient.writeObject(result);
LOGGER.debug("Result of required service was sent to client.");
inFromClient.close();
outToClient.close();
//clientSocket.close();
}catch(IOException ex){
LOGGER.error("Exception caught when trying to listen on port "
+ " or listening for a connection");
ex.printStackTrace();
}
catch(ClassNotFoundException ex){
LOGGER.error("class was not found.");
}
}
}
}
// this is client side
package reg.main;
import java.net.*;
import java.io.*;
import java.util.*;
import java.util.Scanner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//Client class
public class Client{
private final static Logger LOGGER = LoggerFactory.getLogger(Client.class);
public static void main(String[] args){
Socket clientSocket = null;
String userOption;
InputStream inputStream = null;
Properties prop = new Properties();
try{
String filename = "config.properties";
inputStream = Client.class.getClassLoader().getResourceAsStream(filename);
if(inputStream == null){
System.out.println("Sorry, unable to find " + filename);
}
prop.load(inputStream);
}
catch(IOException ex){
System.out.println("properties file does not exist.");
}
try{
Scanner input = new Scanner(System.in);
System.out.println("Do you want to sign in or login? put the file name in:");
String path = input.next();
LOGGER.debug("User entered " + path + " as the service option.");
String port = prop.getProperty("port");
int portNo = Integer.parseInt(port);
FileReader fileReader = new FileReader(path);
BufferedReader reader = new BufferedReader(fileReader);
userOption = reader.readLine();
clientSocket = new Socket("192.168.121.114", portNo);
System.out.println("client is connected to the server.");
ObjectOutputStream outToServer = new ObjectOutputStream(clientSocket.getOutputStream());
ObjectInputStream inFromServer = new ObjectInputStream(clientSocket.getInputStream());
outToServer.writeObject(userOption);
LOGGER.debug("sent the user option to server ==> " + userOption);
List<String> listOfparams =(List<String>)inFromServer.readObject();
LOGGER.debug("List of Requierements in Client " + listOfparams);
List<String> info = new ArrayList<String>();
for(String param : listOfparams){
System.out.println("Enter your " + param + ": ");
info.add(input.next());
}
outToServer.writeObject(info);
String result = (String)inFromServer.readObject();
LOGGER.debug("The result of required service: " + result);
System.out.println(clientSocket.isClosed());
inFromServer.close();
outToServer.close();
clientSocket.close();
} catch (UnknownHostException e) {
LOGGER.error("Don't know about host ");
System.exit(1);
} catch (IOException e){
LOGGER.error("Couldn't get I/O for the connection to the host or there is no service for loading");
System.exit(1);
}
catch(ClassNotFoundException ex){
LOGGER.error("class does not found.");
}
}
}
I appreciate any help. Thank u in advance

Use break in catch
try{
String filename = "config.properties";
input = Application.class.getClassLoader().getResourceAsStream(filename);
if(input == null){
System.out.println("Sorry, unable to find " + filename);
}
prop.load(input);
}
catch(IOException ex){
System.out.println("properties file does not exist.");
break; // this make program to go out of the loop
}

Related

Trouble writing to OutputStream socket

I am writing a simple web server program for class that sends files to the web browser on request. I have written as much as I could. The difficulty is getting the data written to the OutputStream. I don't know what I am missing. I couldn't get the simple request to show up on the web browser.
I wrote it to the "name" OutputStream but when I reload the tab in the browser with the URL: "http://localhost:50505/path/file.txt" or any other like that "localhost:50505" it doesn't show up what I wrote to the OutputStream "name". It is supposed to show that.
package lab11;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketImpl;
import java.util.Scanner;
import java.io.OutputStream;
import java.io.PrintWriter;
public class main {
private static final int LISTENING_PORT = 50505;
public static void main(String[] args) {
ServerSocket serverSocket;
try {
serverSocket = new ServerSocket(LISTENING_PORT);
}
catch (Exception e) {
System.out.println("Failed to create listening socket.");
return;
}
System.out.println("Listening on port " + LISTENING_PORT);
try {
while (true) {
Socket connection = serverSocket.accept();
System.out.println("\nConnection from "
+ connection.getRemoteSocketAddress());
handleConnection(connection);
}
}
catch (Exception e) {
System.out.println("Server socket shut down unexpectedly!");
System.out.println("Error: " + e);
System.out.println("Exiting.");
}
}
public static void handleConnection(Socket sok) {
try {
// Scanner in = new Scanner(sok.getInputStream());
InputStream one = sok.getInputStream();
InputStreamReader isr = new InputStreamReader(one);
BufferedReader br = new BufferedReader(isr);
String rootDirectory = "/files";
String pathToFile;
// File file = new File(rootDirectory + pathToFile);
StringBuilder request = new StringBuilder();
String line;
line = br.readLine();
while (!line.isEmpty()) {
request.append(line + "\r\n");
line = br.readLine();
}
// System.out.print(request);
String[] splitline = request.toString().split("\n");
String get = null;
String file = null;
for (String i : splitline) {
if (i.contains("GET")) {
get = i;
String[] splitget = get.split(" ");
file = splitget[1];
}
}
}
OutputStream name = sok.getOutputStream();
Boolean doesexist = thefile.exists();
if (doesexist.equals(true)) {
PrintWriter response = new PrintWriter(System.out);
response.write("HTTP/1.1 200 OK\r\n");
response.write("Connection: close\r\n");
response.write("Content-Length: " + thefile.length() + "\r\n");
response.flush();
response.close();
sendFile(thefile, name);
} else {
System.out.print(thefile.exists() + "\n" + thefile.isDirectory() + "\n" + thefile.canRead());
}
}
catch (Exception e) {
System.out.println("Error while communicating with client: " + e);
}
finally { // make SURE connection is closed before returning!
try {
sok.close();
}
catch (Exception e) {
}
System.out.println("Connection closed.");
}
}
private static void sendFile(File file, OutputStream socketOut) throws
IOException {
InputStream in = new BufferedInputStream(new FileInputStream(file));
OutputStream out = new BufferedOutputStream(socketOut);
while (true) {
int x = in.read(); // read one byte from file
if (x < 0)
break; // end of file reached
out.write(x); // write the byte to the socket
}
out.flush();
}
}
So, I don't know what I really did wrong.
When I load the browser with localhost:50505 it just says can't connect or localhost refused to connect.
You are writing the HTTP response in System.out. You should write it in name, after the headers, in the body of the response. You probably want to describe it with a Content-Type header to make the receiver correctly show the file.

Why is my else if code not running on a Server side? I want to get the input printed given number of times loop is running on client side

MyServer.java
import java.io.*;
import java.net.*;
public class MyServer {
public static void main(String[] args){
try{
ServerSocket ss=new ServerSocket(5001);
Socket s=ss.accept();//establishes connection
DataInputStream dis=new DataInputStream(s.getInputStream());
String str=(String)dis.readUTF();
System.out.println("message= "+str);
DataOutputStream dout=new DataOutputStream(s.getOutputStream());
if ("Hi".equals(str)){
dout.writeUTF("How are you?");
} else if ("Bye".equals(str)){
dout.writeUTF("Thankyou! Have a Good day!");
} **else if (str != null)){
try {
String numbers;
numbers = str.replaceAll("[^0-9]", "");
int number = Integer.parseInt(numbers);
dout.writeUTF("The line is being printed");
for (int i = 0; i < number; i++) {
dout.writeUTF(str.replaceAll("[^a-z,^A-Z]", ""));
}
} catch (Exception e) {
//TODO: handle exception
}**
} else {
dout.writeUTF("Sorry!");
}
dout.flush();
dout.close();
s.close();
ss.close();
} catch(Exception e) {
System.out.println(e);
}
}
}
MyClient.java
import java.io.*;
import java.net.*;
import java.util.*;
public class MyClient {
public static void main(String[] args) {
try{
Scanner sc = new Scanner(System.in);
Socket s=new Socket("localhost",5001);
DataOutputStream dout=new DataOutputStream(s.getOutputStream());
String str1= sc.nextLine();
dout.writeUTF(str1);
dout.flush();
DataInputStream dis=new DataInputStream(s.getInputStream());
String str=(String)dis.readUTF();
System.out.println("message= "+str);
dout.close();
dis.close();
s.close();
} catch(Exception e) {
System.out.println(e);}
}
}
I am giving input to the server from the client-side and want that input to be printed given a number of times on the client-side. But not able to do that. Can anyone let me know what mistake I am making here? It is replying to message "Hi" and "Bye", everything else is working fine.
The following is your code with my corrections.
(Notes after the code.)
Class MyServer
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class MyServer {
public static void main(String[] args) {
try (ServerSocket ss = new ServerSocket(5001)) {
Socket s = ss.accept();// establishes connection
InputStream is = s.getInputStream();
DataInputStream dis = new DataInputStream(is);
String str = dis.readUTF();
System.out.println("message= " + str);
DataOutputStream dout = new DataOutputStream(s.getOutputStream());
if ("Hi".equals(str.trim())) {
dout.writeUTF("How are you?");
}
else if ("Bye".equals(str)) {
dout.writeUTF("Thankyou! Have a Good day!");
}
else if (str != null) {
try {
String numbers;
numbers = str.replaceAll("[^0-9]", "");
int number = Integer.parseInt(numbers);
dout.writeUTF("The line is being printed");
for (int i = 0; i < number; i++) {
dout.writeUTF(str.replaceAll("[^a-z,^A-Z]", ""));
}
}
catch (Exception e) {
e.printStackTrace();
}
}
dout.writeUTF("END");
dout.flush();
}
catch (Exception e) {
e.printStackTrace();
}
try {
Thread.sleep(2000L);
}
catch (InterruptedException xInterrupted) {
// Ignore.
}
}
}
Class MyClient
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.net.Socket;
import java.util.Scanner;
public class MyClient {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str1 = sc.nextLine();
try (Socket s = new Socket("localhost", 5001)) {
DataOutputStream dout = new DataOutputStream(s.getOutputStream());
dout.writeUTF(str1);
dout.flush();
InputStream is = s.getInputStream();
DataInputStream dis = new DataInputStream(is);
String str = dis.readUTF();
while (!"END".equals(str)) {
System.out.println("message= " + str);
str = dis.readUTF();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Sending and receiving data via sockets is not instantaneous. Method readUTF will wait until there is data to read. It will read all the data sent in the last invocation of method writeUTF. Method readUTF will wait indefinitely. Hence the server needs to send notification to the client that there is no more data to send. In the above code I send the string END to indicate the end of the data that the server is sending. Note also that you only need to close resources that you explicitly create. In class MyServer, this means ServerSocket only. I use try-with-resources to ensure that ServerSocket is closed.
Similarly, in class MyClient, the only resource that needs to be explicitly closed is the Socket – which I again do using try-with-resources.
If the server terminates, the socket is closed. Hence, in class MyServer, after sending data to the client, the server waits for two seconds which is hopefully enough time for the client to read that data.

how to run config server when the port is args[0] in eclipse

This is my simple server program with java's ServerSocket class.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
public class SimpleServerSocketTest {
public static void main(String[] args) {
while (true)
{
try {
if (args.length != 1) {
System.err.println("Usage: java StartServer <port>");
System.exit(1);
}
int port = Integer.parseInt(args[0]);
ServerSocket server = new ServerSocket(port);
System.out.println("Waiting for client...on " + port);
Socket client = server.accept();
System.out.println("Client from /" + client.getInetAddress() + " connected.");
BufferedReader rdr = new BufferedReader(new InputStreamReader(client.getInputStream(), "UTF-8"));
Writer out = new OutputStreamWriter(client.getOutputStream());
String nameClient = rdr.readLine();
System.out.println("Client " + nameClient + " wants to start a game.");
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
}
I am trying to run config the server
but it keeps on saying this "Usage: java StartServer ".
I want to know how can I config the port when the port is args[0].
This is in Eclipse, by the way.
If it keeps saying "Usage: java StartServer" it therefore means this code
System.err.println("Usage: java StartServer <port>");
Is always been executed which means the condition
args.length != 1
Is always true. This could mean args.length = 0 or args.length > 1
Did you make eclipse pass the port number when running your application? That is did you configure any command line arguments to be used? I'm not a user eclipse so I can't help you here. See if this tutorial is helpful http://www.concretepage.com/ide/eclipse/how-to-pass-command-line-arguments-to-java-program-in-eclipse or you could try to find some other tutorial.
Also make sure you didn't pass too many arguments than is required because that will also make the condition to return true. Just pass as many arguments to make the condition args.length != 1 fail which is having 1 argument.
You can also see this question with help configuring command line arguments in eclipse.
This is my practice for you.
Copy and complete your code.
Select menu clicking right button of your mouse, Run > Run Configurations
Select Arguments tab and type a port number whatever you want your server to wait for client connection then, run it.
Test it with your client socket program.
This is my practice using client socket programming.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class SimpleClientSocketTest {
public static void main(String[] args) {
BufferedReader rdr = null;
Socket sock = null;
PrintWriter out = null;
try{
sock = new Socket("localhost", 9999);
rdr = new BufferedReader(new InputStreamReader(sock.getInputStream(), "UTF-8"));
out = new PrintWriter(sock.getOutputStream(), true);
String toServer = "hello...";
out.println(toServer + "i wants to start a game.");
String fromServer = rdr.readLine();
System.out.println("server: " + fromServer);
if(fromServer == null) System.exit(0);
} catch (IOException e) {
e.printStackTrace();
}
finally
{
try {
rdr.close();
out.flush();
out.close();
sock.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Send a message to the server first,
out.println(toServer + "i wants to start a game.");
then, receive from the server.
String fromServer = rdr.readLine();
System.out.println("server: " + fromServer);
There is one more thing to tell you about your server program.
This is a customized version of yours.
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 SimpleServerSocketTest {
public static void main(String[] args) {
if (args.length != 1) {
System.err.println("Usage: java StartServer <port>");
System.exit(1);
}
int port = Integer.parseInt(args[0]);
ServerSocket server = null;
try {
server = new ServerSocket(port);
} catch (IOException e2) {
e2.printStackTrace();
}
while (true) {
BufferedReader rdr = null;
PrintWriter out = null;
int clientConnectionCnt = 0;
try {
System.out.println("1Waiting for client...on " + port);
Socket client = server.accept();
if(client.isConnected())
{
System.out.println("Client from /" + client.getInetAddress() + " connected.");
String nameClient = null;
try {
rdr = new BufferedReader(new InputStreamReader(client.getInputStream(), "UTF-8"));
out = new PrintWriter(client.getOutputStream(), true);
System.out.println("clientConnectionCnt....." + clientConnectionCnt++);
nameClient = rdr.readLine();
out.println("Yes, You can");
if(nameClient == null) break;
System.out.println("Client: " + nameClient);
} catch (IOException e) {
e.printStackTrace();
break;
} finally {
out.flush();
rdr.close();
out.close();
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
break;
}
}
try {
server.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
First, you should create a server socket outside of while statement not in a while.
try {
server = new ServerSocket(port);
} catch (IOException e2) {
e2.printStackTrace();
}
Just wait in a while statement util client socket accepting.
while (true) {
.... skip ...
System.out.println("1Waiting for client...on " + port);
Socket client = server.accept();
Then, create in/out stream of client socket.
rdr = new BufferedReader(new InputStreamReader(client.getInputStream(), "UTF-8"));
out = new PrintWriter(client.getOutputStream(), true);
Finally, read and write a message with the socket's stream.
nameClient = rdr.readLine();
out.println("Yes, You can");
Regards, Rach.

iterative dictionary server in java

what it do..
1. an iterative dictionary server that is listening clients requests..
2. connection will be established..
3. server will accept input string from client..
4. then server will search meaning of string from a file..
5. then server will return meaning to the client..
problem is with the while loop of server.. if it finds word it will send that word's meaning to client..fine.. but if word is not found... this
if(d.equals(null)){
input="No knowledge";
out.println(input);
out.flush();
}
doesn't execute... client says null and server says null exception...
what i am doing wrong here... i'm not getting it...!!
i have tried to changed this code...
client-server online dictionary program in java
client:
import java.io.;
import java.net.;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class DCC1 {
public static void main(String[] args) throws IOException {
final int PORT = 8888;
Socket s = null;
PrintWriter out = null;
try {
s = new Socket("localhost", PORT);
out = new PrintWriter(s.getOutputStream()); // Output stream to the server
}
catch (UnknownHostException ex) {
System.err.println("Unknown host: " + PORT);
System.err.println("Exception: " + ex.getMessage());
System.exit(1);
}
catch (IOException ex) {
System.err.println("Cannot get I/O for " + PORT);
System.err.println("Exception: " + ex.getMessage());
System.exit(1);
}
Scanner user = new Scanner(System.in); // Scanning for user input
System.out.print("Enter String: ");
String input;
input = user.next(); // Hold the input from the user
out.println(input); // Send it to the server
out.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream( )));
System.out.println(br.readLine());
out.close();
s.close();
}
}
server:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class DSC1
{
public static void main(String[] args) throws IOException
{
final int PORT = 8888;
final String FILE_NAME = "dictionary.dat";
ServerSocket server = new ServerSocket(PORT);
Socket s = null;
PrintWriter out = null;
Scanner in = null;
FileInputStream fin = null;
ObjectInputStream oin = null;
while (true)
{
try
{
s = server.accept();
}
catch (IOException ex)
{
System.err.println("Accept failed");
System.err.println("Exception: " + ex.getMessage());
System.exit(1);
}
System.out.println("Accepted connection from client");
try
{
in = new Scanner(s.getInputStream()); // Input stream from the client
out = new PrintWriter(s.getOutputStream()); // Output stream to the client
String temp = in.next(); // String holding the word sent from the client
System.out.println("From the client " + temp);
String input = null;
fin = new FileInputStream(FILE_NAME);// The dictionary file
oin = new ObjectInputStream(fin);
dictionary d = (dictionary)oin.readObject();
while(d!= null)
{
System.out.println("in loop...");
if(d.name.equals(temp)){
input=d.meaning;
d.printDic();
out.println(input);
out.flush();
break;
}
d = (dictionary)oin.readObject();
if(d.equals(null))
{
input="No knowledge";
out.println(input);
out.flush();
}
}
}
catch (ClassNotFoundException|IOException ex)
{
System.err.println("Exception: " + ex.getMessage());
System.out.println("Closing connection with client");
in.close();
System.exit(1);
}
in.close();
}
}
}
Don't use d.equals(null). If you want to check if d is null, just do if (d==null).
Why? There's no way this can return true, so probably that's the reason why this code never executes and you don't get what you expect.

multithread client-server chat, using sockets

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()));

Categories

Resources