Chat program using TCP : Only first message reaches other end - java

I was writing a TCP chat program.
Here is my output.
As you can see only first message from each peer is reaching the other end.
Second message on wards are not displayed.
Here is my full code. You can run it. Where am I wrong?
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import javax.swing.*;
class chattcp extends JFrame {
public static void main(String args[]){
chattcp peer1=new chattcp("peer1",9999,9998);
chattcp peer2=new chattcp("peer2",9998,9999);
}
chattcp(String name,int lis,int snd){
this.setVisible(true);
this.setTitle(name);
this.setLayout(null);
this.setSize(500,500);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TextField tf=new TextField();
this.add(tf);
tf.setBounds(10,20,100,40);
TextArea ta=new TextArea();
this.add(ta);
ta.setBounds(10,80,400,400);
ta.setEditable(false);
ta.setFont(ta.getFont().deriveFont(20f));
Button b=new Button("send");
this.add(b);
b.setBounds(130,20,60,40);
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent a){
try{
String s= tf.getText();
Socket skt=new Socket("localhost",snd);
DataOutputStream dos= new DataOutputStream(skt.getOutputStream());
dos.writeUTF(s);
ta.append("You :"+s+"\n");
tf.setText("");
}
catch(IOException e){
e.printStackTrace();
}
}
});
Thread receive=new Thread() {
public void run(){
try{
ServerSocket ser=new ServerSocket(lis);
Socket sktt=ser.accept();
DataInputStream dis= new DataInputStream(sktt.getInputStream());
while (true){
String s= dis.readUTF();
ta.append("Friend : "+s+"\n");
}
}catch(IOException e){e.printStackTrace();}
}
};
receive.start();
}
}

Everytime you click your send button you create a new socket and try to connect.
The problem is, once you send something, the socket is created, the serversocket accepts and starts the loop.
When you now write the second message, you are creating a new socket while the loop is still trying to read from the OutputStream from the old socket.
one solution to your problem is to close the serversocket after each read and create a new serversocket each iteration:
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import javax.swing.*;
public class chattcp extends JFrame {
public static void main(String args[]) {
chattcp peer1 = new chattcp("peer1", 9999, 9998);
chattcp peer2 = new chattcp("peer2", 9998, 9999);
}
chattcp(String name, int lis, int snd) {
this.setVisible(true);
this.setTitle(name);
this.setLayout(null);
this.setSize(500, 500);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TextField tf = new TextField();
this.add(tf);
tf.setBounds(10, 20, 100, 40);
TextArea ta = new TextArea();
this.add(ta);
ta.setBounds(10, 80, 400, 400);
ta.setEditable(false);
ta.setFont(ta.getFont().deriveFont(20f));
Button b = new Button("send");
this.add(b);
b.setBounds(130, 20, 60, 40);
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent a) {
try {
String s = tf.getText();
Socket skt = new Socket("localhost", snd);
DataOutputStream dos = new DataOutputStream(skt.getOutputStream());
dos.writeUTF(s);
ta.append("You :" + s + "\n");
tf.setText("");
} catch (IOException e) {
e.printStackTrace();
}
}
});
Thread receive = new Thread() {
public void run() {
try {
while (true) {
ServerSocket ser = new ServerSocket(lis);
Socket sktt = ser.accept();
DataInputStream dis = new DataInputStream(sktt.getInputStream());
String s = dis.readUTF();
ta.append("Friend : " + s + "\n");
ser.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
receive.start();
}
}
a better solution would be to not always create a new socket, when you send something, but i am lazy and this solution is easier to edit your code to, so i just used it.

You are creating a new connection every time that you click on the send button, but the Server only listen one time.
One simple answer is to save the Socket e reuse it.
class chattcp extends JFrame {
public static void main(String args[]){
chattcp peer1=new chattcp("peer1",9999,9998);
chattcp peer2=new chattcp("peer2",9998,9999);
}
Socket skt = null;
chattcp(String name,int lis,int snd){
this.setVisible(true);
this.setTitle(name);
this.setLayout(null);
this.setSize(500,500);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TextField tf=new TextField();
this.add(tf);
tf.setBounds(10,20,100,40);
TextArea ta=new TextArea();
this.add(ta);
ta.setBounds(10,80,400,400);
ta.setEditable(false);
ta.setFont(ta.getFont().deriveFont(20f));
Button b=new Button("send");
this.add(b);
b.setBounds(130,20,60,40);
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent a){
try{
if (skt == null) {
skt = new Socket("localhost",snd);
}
DataOutputStream dos= new DataOutputStream(skt.getOutputStream());
String s= tf.getText();
dos.writeUTF(s);
ta.append("You :"+s+"\n");
tf.setText("");
}
catch(IOException e){
e.printStackTrace();
}
}
});
Thread receive=new Thread() {
public void run(){
try{
ServerSocket ser=new ServerSocket(lis);
Socket sktt=ser.accept();
DataInputStream dis= new DataInputStream(sktt.getInputStream());
while (true){
String s= dis.readUTF();
ta.append("Friend : "+s+"\n");
}
}catch(IOException e){e.printStackTrace();}
}
};
receive.start();
}
}

Related

Java: Using AWT button to disconnect from chat server

I am programming a simple multi-threaded client/server chat system. Project requirements specify: "Connection only happens when the connect button is clicked. The disconnect button should disconnect the connection. A user should be able to connect, disconnect, re-connect at will." Basically, I have the connect button hooked-up and running. However, when I attempt to disconnect I get stuck in an infinite loop where the client side (on command line) infinitely prints "Sock closed", while the server side infinitely prints "Message read: null". This has lead me to look into all of my for(;;) loops to somehow close the connections within them, however I cannot figure out how to close the connection within those loops. Please help, this is my first socket programming project and I am super stumped on this one! Thanks all.
Client:
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.ArrayList;
public class ClientFrame extends Frame{
public ClientFrame(){
setSize(500,500);
setTitle("Chat Client");
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent We){
System.exit(0);
}
});
add(new ClientPanel(), BorderLayout.CENTER);
setVisible(true);
}
public static void main(String[] args){
new ClientFrame();
}
} // end ClientFrame
class ClientPanel extends Panel implements ActionListener, Runnable{
TextField tf;
TextArea ta;
List list;
Button connect, disconnect;
Socket socketToServer;
PrintWriter pw;
BufferedReader br;
Thread t;
String userName;
public ClientPanel(){
setLayout(new BorderLayout());
tf = new TextField();
ta = new TextArea();
list = new List();
connect = new Button("Connect");
disconnect = new Button("Disconnect");
Panel bPanel = new Panel();
bPanel.add(connect);
disconnect.setEnabled(false);
bPanel.add(disconnect);
tf.addActionListener(this);
add(tf, BorderLayout.NORTH);
add(ta, BorderLayout.CENTER);
add(list, BorderLayout.EAST);
add(bPanel, BorderLayout.SOUTH);
connect.addActionListener(this);
disconnect.addActionListener(this);
} // end ClientPanel constructor
public void actionPerformed(ActionEvent ae){
if (ae.getSource() == tf){
String temp = tf.getText();
pw.println(userName+": "+temp);
tf.setText("");
} else if (ae.getSource() == connect){
if(tf.getText() == null || tf.getText().equals("")){
ta.append("Must enter a name to connect\n");
}else {
userName = tf.getText();
connect.setEnabled(false);
disconnect.setEnabled(true);
tf.setText("");
try{
socketToServer = new Socket("127.0.0.1", 3000);
pw = new PrintWriter(new OutputStreamWriter
(socketToServer.getOutputStream()), true);
br = new BufferedReader(new InputStreamReader
(socketToServer.getInputStream()));
}catch(UnknownHostException uhe){
System.out.println(uhe.getMessage());
}catch(IOException ioe){
System.out.println(ioe.getMessage());
}
}
t = new Thread(this);
t.start();
pw.println(userName);
pw.println(userName +" has entered the chat.");
}else if (ae.getSource()== disconnect){
try{
t.interrupt();
socketToServer.close();
}catch(IOException ioe){
System.out.println(ioe.getMessage());
}
}
} // end actionPerformed
public void run(){
for(;;){
try{
String temp = br.readLine();
ta.append(temp + "\n");
}catch(IOException ioe){
System.out.println(ioe.getMessage());
}
}
} // end run
} // end ClientPanel
Server:
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.awt.*;
public class ThreadedServerWithPresence{
public static void main(String[] args){
ArrayList<ThreadedHandlerWithPresence> handlers;
try{
handlers = new ArrayList<ThreadedHandlerWithPresence>();
ServerSocket s = new ServerSocket(3000);
for(;;){
Socket incoming = s.accept( );
new ThreadedHandlerWithPresence(incoming,
handlers).start();
}
}catch (Exception e){
System.out.println(e);
}
}
}
class ThreadedHandlerWithPresence extends Thread{
Socket incoming;
ArrayList<ThreadedHandlerWithPresence> handlers;
PrintWriter pw;
BufferedReader br;
String userName;
public ThreadedHandlerWithPresence(Socket i,
ArrayList<ThreadedHandlerWithPresence> handlers){
incoming = i;
this.handlers = handlers;
handlers.add(this);
}
public void setUserName(String userName){
this.userName = userName;
}
public String getUserName(){
return userName;
}
public void run(){
try{
br = new BufferedReader(new InputStreamReader
(incoming.getInputStream()));
pw = new PrintWriter(new OutputStreamWriter
(incoming.getOutputStream()),true);
String firstLine = br.readLine();
setUserName(firstLine);
for(;;){
String temp = br.readLine();
System.out.println("Message read: " + temp);
for(int i = 0; i < handlers.size(); i++){
handlers.get(i).pw.println(temp);
}
}
}catch (Exception e){
System.out.println(e);
}finally{
handlers.remove(this);
}
}
}
Client
Your run method does not handle interruptions so the for loop does not end and it continues trying to receive messages.
You must add an action that can be interrupted and throws InterruptedException, Thread.sleep would be a good candidate in this case, also reducing CPU usage (You do not need to check for new messages every single moment).
try {
for (; ; ) {
try {
String temp = br.readLine();
ta.append(temp + "\n");
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
}
Thread.sleep(10);
}
} catch (InterruptedException e) {
System.out.println("Disconnected.");
}
Server
When br.readLine() returns null, that indicates the connection is closed by the client and you should stop receiving messages.
String temp = br.readLine();
if(temp == null)
break;

How do you know how to limit how many client that could enter your basic group chat app server? (Maximum 10)

so here is my code :
Server.java
import java.io.*;
import java.net.*;
import java.util.*;
class Server implements Runnable{
Socket connectionSocket;
public static Vector clients=new Vector();
public Server(Socket s){
try{
System.out.println("Client Got Connected " );
connectionSocket=s;
}catch(Exception e){e.printStackTrace();}
}
public void run(){
try{
BufferedReader reader =
new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
BufferedWriter writer=
new BufferedWriter(new OutputStreamWriter(connectionSocket.getOutputStream()));
clients.add(writer);
while(true){
String data1 = reader.readLine().trim();
System.out.println("Received : "+data1);
for (int i=0;i<clients.size();i++){
try{
BufferedWriter bw= (BufferedWriter)clients.get(i);
bw.write(data1);
bw.write("\r\n");
bw.flush();
}catch(Exception e){e.printStackTrace();}
}
}
}catch(Exception e){e.printStackTrace();}
}
public static void main(String argv[]) throws Exception{
System.out.println("Threaded Chat Server is Running " );
ServerSocket mysocket = new ServerSocket(5555);
while(true){
Socket sock = mysocket.accept();
Server server=new Server(sock);
Thread serverThread=new Thread(server);
serverThread.start();
}
}
}
mychat.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
public class mychat implements Runnable
{
public JTextField tx;
public JTextArea ta;
public String login="Imed";
BufferedWriter writer;
BufferedReader reader;
public mychat(String l)
{
login=l;
ClientName z = new ClientName();
JFrame f=new JFrame(z.getName()+"'s Chat");
f.setSize(400,400);
JPanel p1=new JPanel();
p1.setLayout(new BorderLayout());
JPanel p2=new JPanel();
p2.setLayout(new BorderLayout());
tx=new JTextField();
p1.add(tx, BorderLayout.CENTER);
JButton b1=new JButton("Send");
p1.add(b1, BorderLayout.EAST);
ta=new JTextArea();
p2.add(ta, BorderLayout.CENTER);
p2.add(p1, BorderLayout.SOUTH);
f.setContentPane(p2);
try
{
Socket socketClient= new Socket("localhost",5555);
writer= new BufferedWriter(new OutputStreamWriter(socketClient.getOutputStream()));
reader =new BufferedReader(new InputStreamReader(socketClient.getInputStream()));
}
catch(Exception e){e.printStackTrace();}
b1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ev)
{
String s=login+" : "+tx.getText();
tx.setText("");
try
{
writer.write(s);
writer.write("\r\n");
writer.flush();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
);
f.setVisible(true);
}
public void run()
{
try
{
String serverMsg="";
while((serverMsg = reader.readLine()) != null)
{
System.out.println("from server: " + serverMsg);
ta.append(serverMsg+"\n");
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
startclient.java
public class startclient
{
public static void main(String [] args)
{
try
{
ClientName n = new ClientName();
mychat c=new mychat(n.getName());
Thread t1=new Thread(c);
t1.start();
}
catch(Exception e){e.printStackTrace();}
}
}
And last ClientName.java
import java.util.*;
public class ClientName
{
String name;
public String getName()
{
Scanner sc = new Scanner(System.in);
System.out.print ("Enter your name : ");
name = sc.nextLine();
return name;
}
}
So basically, i want to limit how many client that could join my server(which maximum is 10 client). And if there is another client that want to join the server after it is full, that client will be rejected so it cannot joined.
I think that's it, though if there are any other improvement in other areas at my code it will also be appreciated. Sorry for my bad english
*Oh and sorry since I forget to include it, but somehow when I start the client, it ask the name twice
You can fix main method in your server and add sayGoodBye() as follows:
private static final int CONNECTION_LIMIT = 10;
public static void main(String argv[]) throws Exception {
System.out.println("Threaded Chat Server is Running ");
ServerSocket mysocket = new ServerSocket(5555);
int socketCount = 0;
while (true) {
Socket sock = mysocket.accept();
Server server = new Server(sock);
if (socketCount++ < CONNECTION_LIMIT) {
Thread serverThread = new Thread(server);
serverThread.start();
} else {
// without starting a thread and notifying only new client
server.sayGoodbye();
}
}
}
public void sayGoodbye() throws IOException {
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(connectionSocket.getOutputStream()))) {
writer.write("Sorry, new client connections are not accepted, bye for now");
} catch (Exception e) {
e.printStackTrace();
}
connectionSocket.close();
}

How to fix error: constructor Server in class Server cannot be applied to given types

Here is my code:
Server.java
import java.io.*;
import java.net.*;
import java.util.*;
class Server implements Runnable{
static int socketCount = 0;
Socket connectionSocket;
public static Vector clients=new Vector();
public Server(Socket s){
try{
System.out.println("Client Got Connected " );
connectionSocket=s;
}catch(Exception e){e.printStackTrace();}
}
public void run(){
try{
BufferedReader reader =
new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
BufferedWriter writer=
new BufferedWriter(new OutputStreamWriter(connectionSocket.getOutputStream()));
clients.add(writer);
while(true){
String data1 = reader.readLine().trim();
System.out.println("Received : "+data1);
for (int i=0;i<clients.size();i++){
try{
BufferedWriter bw= (BufferedWriter)clients.get(i);
bw.write(data1);
bw.write("\r\n");
bw.flush();
}catch(Exception e){e.printStackTrace();}
}
}
}catch(Exception e){e.printStackTrace();}
}
private static final int CONNECTION_LIMIT = 10;
public static void main(String argv[]) throws Exception {
System.out.println("Threaded Chat Server is Running ");
ServerSocket mysocket = new ServerSocket(5555);
while (true) {
Socket sock = mysocket.accept();
Server server = new Server(sock);
if (socketCount++ < CONNECTION_LIMIT) {
Thread serverThread = new Thread(server);
serverThread.start();
} else {
// without starting a thread and notifying only new client
socketCount--;
server.sayGoodbye();
}
}
}
public void sayGoodbye() throws IOException
{
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(connectionSocket.getOutputStream())))
{
writer.write("Sorry, a new client connections are exceeding the server limit thus it will not be accepted");
} catch (Exception e)
{
e.printStackTrace();
}
connectionSocket.close();
}
public int getSocket()
{
return socketCount;
}
}
mychat.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class mychat implements Runnable
{
public JTextField tx;
public JTextArea ta;
Server asd = new Server();
public String login="Imed";
BufferedWriter writer;
BufferedReader reader;
public mychat(String l)
{
login=l;
startclient z = new startclient();
JFrame f=new JFrame(z.getName()+"'s Chat");
f.setSize(400,400);
JPanel p1=new JPanel();
p1.setLayout(new BorderLayout());
JPanel p2=new JPanel();
p2.setLayout(new BorderLayout());
tx=new JTextField();
p1.add(tx, BorderLayout.CENTER);
JButton b1=new JButton("Send");
p1.add(b1, BorderLayout.EAST);
ta=new JTextArea();
p2.add(ta, BorderLayout.CENTER);
p2.add(p1, BorderLayout.SOUTH);
f.setContentPane(p2);
try
{
Socket socketClient= new Socket("localhost",5555);
writer= new BufferedWriter(new OutputStreamWriter(socketClient.getOutputStream()));
reader =new BufferedReader(new InputStreamReader(socketClient.getInputStream()));
}
catch(Exception e){e.printStackTrace();}
b1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ev)
{
String s=login+" : "+tx.getText();
tx.setText("");
try
{
writer.write(s);
writer.write("\r\n");
writer.flush();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
);
f.setDefaultCloseOperation (JFrame.DO_NOTHING_ON_CLOSE);
f.addWindowListener(new java.awt.event.WindowAdapter() {
#Override
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
if (JOptionPane.showConfirmDialog(f,
"Are you sure you want to close this window?", "Close Window?",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION){
asd.getSocket() = asd.getSocket() - 1;
System.exit(0);
}
}
});
f.setVisible(true);
}
public void run()
{
try
{
String serverMsg="";
while((serverMsg = reader.readLine()) != null)
{
System.out.println("from server: " + serverMsg);
ta.append(serverMsg+"\n");
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
startclient.java
import java.util.*;
public class startclient
{
static String name;
public static void main(String [] args)
{
try
{
Scanner sc = new Scanner(System.in);
System.out.print ("Enter your name : ");
name = sc.nextLine();
mychat c=new mychat(name);
Thread t1=new Thread(c);
t1.start();
}
catch(Exception e){e.printStackTrace();}
}
public String getName()
{
return name;
}
}
Every time I try to compile the mychat.java, I get this error message:
mychat.java:13: error: constructor Server in class Server cannot be applied to given types;
Server asd = new Server();
^
required: Socket
found: no arguments
reason: actual and formal argument lists differ in length
mychat.java:90: error: unexpected type
asd.getSocket() = asd.getSocket() - 1;
^
required: variable
found: value
2 errors
I want to limit how many clients can join the server, which kind of works, by adding a new integer called socketCount at Server.java and then increasing the count every time there are new clients joining and if the number of clients is exceeding the server limit, it will reject it.
But it seems that even though I already close the client, the socketCount value is still not decreasing and thus a new client could not enter even though I already giving it places.
Which is why I try to fix it by decreasing the socketCount value at mychat.java every time I close the program, but this error happens.
How can I resolve the error?
You can see the error log here:
mychat.java:13: error: constructor Server in class Server cannot be applied to given types;
Server asd = new Server();
That means you have to put the Socket whenever you create the Server instance.
Your constructor here:
public Server(Socket s){
try{
System.out.println("Client Got Connected " );
connectionSocket=s;
}catch(Exception e){e.printStackTrace();}
}
So, put the Socket to your instance and it should work fine.
Besides that, you should format your codes to be more readable. The class/methods should follow the Coding Convention. It will help you in the future.
Hope this help

Java Client/Server not displaying in ClientGUI

Hi I've been working on a Server/Client Chat Program in which I need a GUI for the client . I've got the basic console Client/Server communicating correctly but I can't get the input/output of the client to display on the Client GUI can somebody please take a look and give me suggestions on as to how I can get the output of the Client to work on the ClientGUI using the text field as input and then broadcasting it to the text area? I've placed my code below.
DATA OBJECT
import java.io.*;
import java.net.*;
public class DataObject implements Serializable{
String message;
public DataObject(){}
public DataObject(String message){
setMessage(message);
}
public void setMessage(String message){
this.message = message;
}
public String getMessage(){
return message;
}
}
ThreadedChatServer
import java.io.*;
import java.net.*;
import java.util.*;
public class ThreadedChatServer{
ThreadedChatClient tcg;
int port;
public ThreadedChatServer(int port){
this.port=port;
try{
ArrayList<ThreadedChatHandler> handlers = new ArrayList<ThreadedChatHandler>();
ServerSocket ss = new ServerSocket(port);
for(;;){
System.out.println("Waiting for clients on port " +port+"...");
System.out.println("If running client from console type 'java ThreadedChatClient [String Username] [String host] [int Port]'");
Socket s = ss.accept();
System.out.println("New user has entered.");
new ThreadedChatHandler(s, handlers).start();
}
}catch(Exception e){
System.out.println(e.getMessage());
}
}
public static void main(String[] args){
ThreadedChatServer tcs= new ThreadedChatServer(1999);
}
}
class ThreadedChatHandler extends Thread{
ThreadedChatClient tcg;
public ThreadedChatHandler(Socket s, ArrayList<ThreadedChatHandler> list){
this.s = s;
this.list = list;
this.list.add(this);
}
public synchronized void broadcast(DataObject d) throws IOException{
for(ThreadedChatHandler handler: list){
handler.oos.writeObject(d);
}
}
public void run(){
try{
ois = new ObjectInputStream(s.getInputStream());
oos = new ObjectOutputStream(s.getOutputStream());
objIn= new DataObject( "User has entered.");
broadcast(objIn);
while(true){
obj = (DataObject)ois.readObject();
broadcast(obj);
}
}catch(Exception e){
System.out.println(e.getMessage());
}finally{
try{
objOut= new DataObject("User has left.");
broadcast(objOut);
list.remove(this);
ois.close();
oos.close();
s.close();
}catch(IOException ioe){
System.out.println(ioe.getMessage());
}
}
}
DataObject obj,objIn,objOut;
Socket s;
ArrayList<ThreadedChatHandler> list;
ObjectInputStream ois;
ObjectOutputStream oos;
}
ThreadedChatClient
DataObject in, out;
ObjectOutputStream oos;
ObjectInputStream ois;
Scanner scan;
String username;
ChatClientGUI cg;
public ThreadedChatClient(String username,String host,int port){
this.username=username;
scan = new Scanner(System.in);
try{
s = new Socket(host,port);
oos = new ObjectOutputStream(s.getOutputStream());
}catch(Exception e){
System.out.println(e.getMessage());
}
this.start();
for(;;){
String temp = scan.nextLine();
out = new DataObject(temp);
try{
out.setMessage(username+": "+out.getMessage());
oos.writeObject(out);
}catch(Exception e){
System.out.println(e.getMessage());
}
}
}
public void run(){
try{
ois = new ObjectInputStream(s.getInputStream());
}catch(Exception e){
System.out.println(e.getMessage());
}
for(;;){
try{
in = (DataObject)ois.readObject();
}catch(Exception e){
System.out.println(e.getMessage());
}
System.out.println(in.getMessage());
}
}
public static void main(String[] args){
ThreadedChatClient c = new ThreadedChatClient(args[0],args[1],Integer.parseInt(args[2]));
}
}
ChatClientGUI
import java.awt.*;
import java.awt.event.*;
public class ChatClientGUI extends Frame implements ActionListener{
Canvas c;
TextField tfServer,tfPort,tfUsername,tf;
TextArea ta;
int defaultPort;
String defaultHost,defaultUsername;
Label label;
Button b,b2;
List lst;
ThreadedChatClient cc;
int finalY,finalX;
public ChatClientGUI(String username,String host,int port){
super("ChatClientGUI");
defaultPort = port;
defaultHost = host;
defaultUsername= username;
setSize(600,600);
addWindowListener(new WindowAdapter (){
public void windowClosing(WindowEvent we){
System.exit(0);
}
});
Panel nPanel = new Panel(new GridLayout(3,1));
Panel serverAndPort = new Panel(new GridLayout());
tfServer = new TextField(host);
tfServer.addActionListener(this);
tfPort = new TextField("" + port);
tfPort.addActionListener(this);
tfUsername= new TextField(defaultUsername);
tfUsername.addActionListener(this);
serverAndPort.add(new Label("Username:"));
serverAndPort.add(tfUsername);
serverAndPort.add(new Label("Server Address: "));
serverAndPort.add(tfServer);
serverAndPort.add(new Label("Port Number: "));
serverAndPort.add(tfPort);
nPanel.add(serverAndPort);
label = new Label("Enter your message below");
nPanel.add(label);
tf = new TextField();
tf.setBackground(Color.WHITE);
nPanel.add(tf);
add(nPanel, BorderLayout.NORTH);
////
Panel cPanel= new Panel(new GridLayout(2,1));
ta= new TextArea();
cPanel.add(ta);
ta.setEditable(false);
c=new Canvas();
c.setBackground(Color.BLACK);
c.setForeground(Color.WHITE);
c.setEnabled(true);
cPanel.add(c);
add(cPanel,BorderLayout.CENTER);
//////
Panel sPanel= new Panel(new GridLayout());
Panel inOutPanel= new Panel(new GridLayout());
b= new Button("Login");
b.addActionListener(this);
b.setBackground(Color.GREEN);
inOutPanel.add(b);
b2= new Button("Logout");
b2.addActionListener(this);
b2.setBackground(Color.RED);
b2.setEnabled(false);
inOutPanel.add(b2);
lst = new List(4,false);
lst.add("*List Of Users*");
inOutPanel.add(lst);
sPanel.add(inOutPanel);
add(sPanel,BorderLayout.SOUTH);
}
public void actionPerformed(ActionEvent e) {
Object o= e.getSource();
if(o==b){
int por=0;
por = Integer.parseInt(tfPort.getText());
ta.append(tfUsername.getText()+" has entered the chat.\n");
b.setEnabled(false);
b2.setEnabled(true);
tfUsername.setEditable(false);
tfServer.setEditable(false);
tfPort.setEditable(false);
lst.add(tfUsername.getText());
tf.setEditable(true);
tf.addActionListener(this);
cc= new ThreadedChatClient(tfUsername.getText(),tfServer.getText(),por);
}
if(o==b2){
ta.append(tfUsername.getText()+" has left the chat.\n");
b.setEnabled(true);
b2.setEnabled(false);
tf.setEditable(false);
tfUsername.setEditable(true);
tfServer.setEditable(true);
tfPort.setEditable(true);
tf.removeActionListener(this);
lst.remove(tfUsername.getText());
}
if(o==tf){
DataObject objt=new DataObject(tfUsername.getText()+": "+tf.getText()+"\n");
ta.append(tfUsername.getText()+": "+tf.getText()+"\n");
tf.setText("");
}
if(o==c){
c.setBackground(Color.BLUE);
}
}
public static void main(String [] args){
ChatClientGUI cc= new ChatClientGUI("unknown","localhost",1999);
cc.setVisible(true);
}
}
Thanks in advance for your help.

java simple chat client query

This is the code that i am using (its not mine)
import java.io.*;
import java.net.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SimpleChatClient {
JTextArea incoming;
JTextField outgoing;
BufferedReader reader;
PrintWriter writer;
Socket sock;
public void go() {
JFrame frame = new JFrame("Ludicrously Simple Chat Client");
JPanel mainPanel = new JPanel();
incoming = new JTextArea(15, 50);
incoming.setLineWrap(true);
incoming.setWrapStyleWord(true);
incoming.setEditable(false);
JScrollPane qScroller = new JScrollPane(incoming);
qScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
qScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
outgoing = new JTextField(20);
JButton sendButton = new JButton("Send");
sendButton.addActionListener(new SendButtonListener());
mainPanel.add(qScroller);
mainPanel.add(outgoing);
mainPanel.add(sendButton);
frame.getContentPane().add(BorderLayout.CENTER, mainPanel);
setUpNetworking();
Thread readerThread = new Thread(new IncomingReader());
readerThread.start();
frame.setSize(650, 500);
frame.setVisible(true);
}
private void setUpNetworking() {
try {
sock = new Socket("127.0.0.1", 5000);
InputStreamReader streamReader = new InputStreamReader(sock.getInputStream());
reader = new BufferedReader(streamReader);
writer = new PrintWriter(sock.getOutputStream());
System.out.println("networking established");
}
catch(IOException ex)
{
ex.printStackTrace();
}
}
public class SendButtonListener implements ActionListener {
public void actionPerformed(ActionEvent ev) {
try {
writer.println(outgoing.getText());
writer.flush();
}
catch (Exception ex) {
ex.printStackTrace();
}
outgoing.setText("");
outgoing.requestFocus();
}
}
public static void main(String[] args) {
new SimpleChatClient().go();
}
class IncomingReader implements Runnable {
public void run() {
String message;
try {
while ((message = reader.readLine()) != null) {
System.out.println("client read " + message);
incoming.append(message + "\n");
}
} catch (IOException ex)
{
ex.printStackTrace();
}
}
}
}
My question is in the incoming reader class
Why does this line---- while ((message = reader.readLine()) != null)
never return null?
Supposedly, the thread went to check this line and on the other side there are no messages for the client, then shouldn't the above line return null?
Can anyone explain a bit of what's going on? I do know about socket connections and all
I just want to know what's going on with getting incoming messages.
You are using blocking functions such as BufferedReader.readLine(). This will block until there is something to read. It won't "check the device and return null if nothing is returned".
You can check if there is any incoming data using BufferedReader.available() and call readLine() if the result is > 0.

Categories