BufferedReader.readline() blocks output - java

I created a console chatapplication, that waits for user input with bufferedreader.readline() and should print chat messages from the partner simultaneously. But after readline() was invoked, no output is possible.
Waiting for messages and Sending Messages is realized in different threads.
public class MsgReader implements Runnable {
private Socket connection;
private final Console con;
public MsgReader(Socket sock, Console con) {
this.connection = sock;
this.con = con;
this.run();
}
#Override
public void run() {
InputStream is = null;
try {
is = connection.getInputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BufferedReader in = new BufferedReader(new InputStreamReader(is));
try {
System.out.println("asdf");
while (true) {
String ss = in.readLine();
// System.out.println((char)in.read());
// System.out.println("asdf");
//
con.write(ss);
// con.write(ss);
Thread.sleep(500);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class MsgWriter implements Runnable {
private Socket connection;
private final Console con;
public MsgWriter(Socket sock, Console con) {
this.connection = sock;
this.con = con;
this.run();
}
#Override
public void run() {
OutputStream os = null;
try {
os = connection.getOutputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
try {
char in = ' ';
boolean running = true;
while (true) {
String ss=In.inString2("");
if(ss.equals("")){
System.out.println("enter your message: ");
//String s = con.readLine();
String s=In.inString2("");
bw.write(s+"\n");
bw.flush();
System.out.println("sent");
}
if(ss.equals("x")){
break;
}
Thread.sleep(500);
}
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("fail ");
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
console
import inout.In;
public class Console {
public Console() {
}
public synchronized void write(String txt) {
System.out.println(txt);
}
public synchronized String readLine() {
String temp=In.inString2("");
return temp;
}
}

Calling run() doesn't start a new thread, it just executes the method. You need to create a new Thread:
Runnable runnable = ...
Thread thread = new Thread(runnable);
thread.start() // <-- actually causes the run() method to be executed asynchronously
Better still would be to use an ExecutorService:
ExecutorService executor = ...
executor.execute(runnable);
As these offer pooling of threads (amongst other features).

Related

Server not sending messages to the clients connected to it

I have created a chat server which is multi threaded and as and when the clients connect it initiates a separate thread for them to communicate. The problem is the my server is not broadcasting messages received from one client to all the other clients connected and I simply do not know how to implement it.
Following is my code, feel free to edit:
The serverclass:
ArrayList<ServerThread> clientlist = new ArrayList();
Hashtable clientList = new Hashtable();
private static ArrayList<PrintWriter> writers = new ArrayList<PrintWriter>();
public ChatServer(JTextField jtfA, JTextField jtfB, JTextArea jtaA, JTextArea tapane3) {
// TODO Auto-generated constructor stub
address= jtfA;
GETPORT=jtfB;
PORT=Integer.parseInt(jtfB.getText());
displaytext=jtaA;
clientside=tapane3;
}
public void run() {
// TODO Auto-generated method stub
try {
InetAddress ad=InetAddress.getLocalHost();
String ip=ad.toString();
address.setText(string);
address.setEditable(false);
System.out.println("Server IP is: " + ad);
ss = new ServerSocket (PORT);
Socket cs = null;
while (true)
{
cs=ss.accept();
System.out.println("Connected"+clientlist);
ServerThread handler = new ServerThread(cs,displaytext,clientside,writers);
clientlist.add(handler);
handler.start();
System.out.println(writers);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getActionCommand().equals("DisConnect"))
{
try {
ss.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
The server thread class::
public class ServerThread extends Thread {
Socket client;
JTextArea display;
JTextArea clients;
ServerSocket server;
ArrayList<PrintWriter> writers ;
public ServerThread(Socket cs, JTextArea displaytext, JTextArea clientside, ArrayList<PrintWriter> writers) {
// TODO Auto-generated constructor stub
client=cs;
display=displaytext;
clients=clientside;
this. writers=writers;
}
public void run () {
try{
BufferedReader br = new BufferedReader(
new InputStreamReader(
client.getInputStream()));
PrintWriter pr = new PrintWriter(
new OutputStreamWriter(
client.getOutputStream()));
String clientMsg="";
boolean all;
do {
//read msg from client
clientMsg = br.readLine();
//display.setText(clientMsg);
System.out.println("Server Received: " + clientMsg);
pr.println(clientMsg);
display.append(clientMsg+"\n");
clients.append(clientMsg+"\n");
pr.flush();
} while((all=br.readLine() != null));
br.close();
pr.close();
while (true) {
String input = br.readLine();
if (input == null) {
return;
}
for (PrintWriter writer : writers) {
writer.println("MESSAGE " + ": " + input);
}
}}
catch (UnknownHostException uhe){
System.out.println("Server issue");
}
catch (IOException ioe){
System.out.println("Server Error IO");
}
catch (Exception e){
System.out.println("Server Error General");
}}
}
Faulty do/while loop. You're throwing away every second line, and not detecting end of stream correctly. It should be:
while ((line = br.readLine()) != null)

Server and Client wont talk to each other

I am trying to make some sort of login system, but the server and client wont talk to each other. I am not quite sure why they wont talk to each other, but any help is appreciated.
P.S The port is correctly set up on my router.
Client
public class Clients implements Runnable
{
String ip = "localhost";
int port = 25565;
Socket client;
static Thread thread;
boolean setup = false;
BufferedReader br;
PrintWriter pw;
public static void main(String[] args)
{
thread = new Thread(new Clients());
thread.start();
}
public void run()
{
while(!setup)
{
try {
client = new Socket(ip,port);
setup = true;
} catch (IOException e) {
setup = false;
}
}
try {
br = new BufferedReader(new InputStreamReader(client.getInputStream()));
pw = new PrintWriter(client.getOutputStream(),true);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
pw.flush();
pw.write("client");
while(true);
}
}
Server
public class Server implements Runnable
{
int port = 25565;
String input;
ServerSocket server;
Socket clients;
BufferedReader br;
PrintWriter pw;
boolean setup = false;
static Thread thread;
public static void main(String[] args)
{
thread = new Thread(new Server());
thread.start();
}
public void run()
{
try {
server = new ServerSocket(port);
clients = server.accept();
br = new BufferedReader(new InputStreamReader(clients.getInputStream()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
System.out.println("getting input");
while((input = br.readLine()) != null)
{
System.out.println(input);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
You should first do write and then flush
pw.write("client\n");
pw.flush();
Also place \n in the line that you are writing since in the client you are doing br.readline(). So it will wait till a new line is available.
I see two problems. The first is that pw.flush should be invoked after pw.write. The second is that the server is waiting on readLine(), which will only return when it encounters a line ending. You should change Clients to invoke pw.write("clients\n"), adding the newline.

Program stop working when try to read input stream

I have a Java Server and one(or more) Android Clients. For now I want them to communicate simply with strings. When i write from android I can get the data in Java Server, but when I try to get the answer from server the Android application stop working. The codes is reported below:
Java Server:
public class Server {
private static int port=12346, maxConnections=0;
// Listen for incoming connections and handle them
public static void main(String[] args) {
int i=0;
try{
ServerSocket listener = new ServerSocket(port);
Socket server;
while((i++ < maxConnections) || (maxConnections == 0)){
doComms connection;
server = listener.accept();
String end = server.getInetAddress().toString();
System.out.println("\n"+end+"\n");
doComms conn_c= new doComms(server);
Thread t = new Thread(conn_c);
t.start();
}
} catch (IOException ioe) {
System.out.println("IOException on socket listen: " + ioe);
ioe.printStackTrace();
}
}
}
class doComms implements Runnable {
private Socket server;
private String line,input;
public doComms(Socket server) {
this.server=server;
}
#SuppressWarnings("deprecation")
public void run () {
input="";
try {
// Get input from the client
DataInputStream in = new DataInputStream (server.getInputStream());
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(server.getOutputStream())),
true);
while((line = in.readLine()) != null && !line.equals(".")) {
input=input + line;
}
JOptionPane.showMessageDialog(null, input);
out.println("Enviado");
server.close();
} catch (IOException ioe) {
System.out.println("IOException on socket listen: " + ioe);
ioe.printStackTrace();
}
}
And Android client's code (it's called every time a button is pressed inside onClick method):
public String enviaMensagem(){
String resposta="";
new Thread(new ClientThread()).start();
Socket socket = null;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;
try {
socket = new Socket(ip, port);
dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream.writeUTF(input.getText().toString());
resposta = dataInputStream.readUTF();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
if (socket != null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dataOutputStream != null){
try {
dataOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dataInputStream != null){
try {
dataInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return resposta;
}
You are using an unsorted mixture of readUTF(), writeUTF(), readLine(), etc. They're not all interoperable. Settle on one of them. If you use writeUTF() you must use readUTF() at the other end. If you use readLine() you must write lines at the other end, with a line terminator such as \r\n or \n.

Socket ObjectOutpuStream ObjectInputStream

I'm writing simple client - server application. Everything is ok but when i change InputStream and OutputStream to ObjectOutputStream and ObjectInputStream my application doesn't send the messages. Can anyone help me and show me the problem ?
Here is the Serwer.java:
class InWorke implements Runnable{
BufferedReader odczyt=null;
String slowo;
ObjectInputStream ois=null;
Message message;
InWorke(ObjectInputStream ois) {
this.ois=ois;
}
public void run() {
while(true) {
try {
slowo = (String) ois.readObject();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(slowo);
Thread.yield();
} }
}
class OutWorke implements Runnable{
Socket socket=null;
BufferedReader odczytWe=null;
DataOutputStream zapis=null;
String slowo=null;
Message message; // it is the simple class to serialization
ObjectOutputStream oos;
OutWorke(Socket socket,ObjectOutputStream oos) {
this.socket=socket;
this.oos=oos;
}
public void run() {
while(true) {
odczytWe=new BufferedReader(new InputStreamReader(System.in));
try {
slowo=odczytWe.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
oos.writeObject(slowo);
oos.flush();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Thread.yield();
}
}
}
public class Klient {
public static void main(String[] args) {
Socket socket=null;
ExecutorService exec=Executors.newCachedThreadPool();
ObjectOutputStream oos=null;
ObjectInputStream ois=null;
try {
socket=new Socket("localhost", 8881);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
//we=socket.getInputStream();
ois=new ObjectInputStream(socket.getInputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
//wy=socket.getOutputStream();
oos=new ObjectOutputStream(socket.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
exec.execute(new OutWorke(socket, oos));
exec.execute(new InWorke(ois));
}
}
Klient.java:
class InWorker implements Runnable{
Socket socket=null;
//InputStream we=null;
//OutputStream wy=null;
String slowo=null;
BufferedReader odczyt=null;
ObjectOutputStream oos;
ObjectInputStream ois;
Message message=null;
InWorker(Socket socket,ObjectInputStream ois) {
this.socket=socket;
this.ois=ois;
}
public void run() {
while(true) {
try {
slowo=(String) ois.readObject();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(slowo);
Thread.yield();
}
}
}
class OutWorker implements Runnable{
DataOutputStream zapis=null;
BufferedReader odczyt=null;
//OutputStream wy=null;
String tekst=null;
ObjectOutputStream oos=null;
Message message;
OutWorker(ObjectOutputStream oos) {
this.oos=oos;
}
public void run() {
while(true) {
odczyt=new BufferedReader(new InputStreamReader(System.in));
try {
tekst=odczyt.readLine();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
oos.writeObject(tekst);
oos.flush();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Thread.yield();
}
}
}
public class Serwer {
public static void main(String[] args) {
ServerSocket serversocket=null;
Socket socket=null;
//InputStream we=null;
//OutputStream wy=null;
ObjectOutputStream oos=null;
ObjectInputStream ois=null;
ExecutorService exec=Executors.newCachedThreadPool();
try {
serversocket=new ServerSocket(8881);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
socket=serversocket.accept();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
ois=new ObjectInputStream(socket.getInputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
oos=new ObjectOutputStream(socket.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
exec.execute(new InWorker(socket, ois));
exec.execute(new OutWorker(oos));
}
}
Check constructor of ObjectInputStream: constructor.
It says:
This constructor will block until the corresponding ObjectOutputStream
has written and flushed the header.
So you need to create and flush corresponding ObjectOutputStream. Now you are creating ObjectInputStreams before output stream for both server and client. They block programs because no output stream is created. You should create output streams first, call flush on them and only then create input streams.
The root issue is just as Nikita points out. The implementation solution is to have the server and client get the input and output streams in the opposite order. If one is getting the inputstream first have the other get the outputstream, etc. I switched the client to get the outputstream first and it all works. I then put it back and change the Server and it all works that way to... you can choose which to change.
For Reference:
http://docs.oracle.com/javase/6/docs/api/index.html?java/io/ObjectOutputStream.html

Socket write error when i connect multiple client to java server simultaneously

I am creating a desktop application in which multiple clients have to connect to the server using socket connection between them. I successfully connected them but the problem occurs when i connect multiple client simultaneously to the server, sever got an error "socket write error"
my code is below plz suggest me an answer..
public class SocketConnection implements Runnable {
// password of oracle database
ServerSocket serverSocket = null;
Socket socket = null;
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;
Socket clientSocket = null;
DBConnection dbConnection;
public SocketConnection() {
// TODO Auto-generated constructor stub
dbConnection = new DBConnection();
if (con != null) {
serverSocket = dbConnection.createSocket();
if (serverSocket != null) {
System.out.println("Server Started. Looking for the connections.");
System.out.println("Listening Port:8888.......");
}
Thread t = new Thread(this);
t.start();
}
}
#Override
public void run() {
// TODO Auto-generated method stub
while (true) {
try {
clientSocket = serverSocket.accept();
System.out.println("Connection Accepted");
Connect m_connect = new Connect(clientSocket);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class Connect implements Runnable {
Socket clientSocket = null;
Thread t = null;
private ResultSet res1;
private ResultSet res2;
Statement stmt;
private File mkFolder;
public Connect(Socket clientSocke) {
// TODO Auto-generated constructor stub
this.clientSocket = clientSocke;
try {
stmt = con.createStatement();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
t = new Thread(this);
t.start();
}
#Override
public void run() {
try {
dataInputStream = new DataInputStream(
clientSocket.getInputStream());
dataOutputStream = new DataOutputStream(
clientSocket.getOutputStream());
System.out.println("Connection established::"
+ clientSocket.getInetAddress());
String pass = dataInputStream.readUTF();
System.out.println(pass);
if (pass.equals("1")) {
//here is read n write operation
} else if (pass.equals("3")) {
//here is read n write operation
} else if (pass.equals("2")) {
//here is read n write operation
} else if (pass.equals("4")) {
//here is read n write operation
} else if (pass.equals("5")) {
//here is read n write operation
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Why you are doing this in that low-level way? Choose an well documented API and communicate through it!
Did you already read articles like this: Multithread client server chat on sockets. Load test. recv failed

Categories

Resources