Swing Socket Testing - java

I am trying a program with Swing.
I am using a socket to connect to the server, and the client has the gui code.
public class FactClient extends JFrame implements ActionListener
{
Socket s;
InputStream in;
OutputStream os;
Scanner sin;
PrintWriter out;
JPanel jp;
JTextField jt;
JButton jb;
JLabel jl;
FactClient()
{
jp = new JPanel();
jt = new JTextField("Enter number",15);
jb = new JButton("Compute Factorial");
jl = new JLabel("Answer");
jb.addActionListener(this);
jp.add(jt);
jp.add(jb);
jp.add(jl);
add(jp);
setVisible(true);
setSize(200,100);
try
{
s = new Socket("localhost",8189);
try
{
in = s.getInputStream();
os = s.getOutputStream();
sin = new Scanner(in);
out = new PrintWriter(os);
out.println("Done with the bingo");
}
finally {}
}
catch(Exception e)
{
System.out.println("Error in client code " + e );
}
}
public void actionPerformed(ActionEvent ae)
{
try {
System.out.println("Connection established " + jt.getText());
String t = jt.getText();
out.println("Ashish");
System.out.println("Data Send");
t = sin.nextLine();
jl.setText(t);
}
catch(Exception e)
{
System.out.println("Error in client code " + e );
}
}
public static void main(String args[])
{
new FactClient();
}
}
import java.io.*;
import java.util.*;
import java.net.*;
public class FactServer
{
public static void main(String args[])
{
ServerSocket s;
Socket socket;
try
{
s= new ServerSocket(8189);
socket = s.accept();
try
{
InputStream in = socket.getInputStream();
OutputStream os = socket.getOutputStream();
// Scanner sin = new Scanner(in);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
PrintWriter ou = new PrintWriter(os);
System.out.println("Connection Established : Stream initailzed");
try
{
String data = br.readLine();
System.out.println("Data Recvd." + data);
data = br.readLine();
}
catch(Exception e)
{
System.out.println("EEEEEEEEEEEEE" + e);
}
//int fact = data +20;
ou.println("40");
}
catch (Exception e)
{
System.out.println("ERROR :P");
}
finally
{
socket.close();
}
}
catch(Exception e)
{
System.out.println("ERROR" + e);
}
}
}
The server code simply reads the data that I send using System.out.println. But the problem is it hangs up; the server never gets the data!
out.println("Done with the bingo");
This is the first string that server should get. But it stays in the wait state as if nothing is received.

You must use flush() after each println() or activate automatic flushing on the PrintWriter so the data gets really sent:
...
out = new PrintWriter(os);
out.println("Done with the bingo");
out.flush();
...
or
...
out = new PrintWriter(os, true); // autoflush
out.println("Done with the bingo");
...
don't forget the server...

Enabling autoflush in your PrintWriter as Carlos said should solve your main question. A couple of other thoughts you might consider:
Wrap the server logic in a loop (e.g. while(true) {...}) if you want it to handle multiple client requests, and handle each request in a separate thread.
Since you are making the client request on the Swing Event Dispatch Thread (i.e. the actionPerformed() method) you might consider wrapping it in a Runnable or SwingWorker so you don't block the dispatch thread. Otherwise you might notice the UI appear to hang or not paint while the socket communication is happening.

Related

Java cannot read and write to socket at the same time

I am trying to build a simple multi client chat application using java sockets. The way I have gone about doing this is by having a client class that connects to a server class that waits for clients to connect and creates a new thread to deal with that client(Where the socket connection is read and written to). The client also reads from and writes to the socket connection to this thread. However, when the client wrote to the output stream of the socket, the server would not respond. A similar question here was posted:
Can you write to a sockets input and output stream at the same time?
One of the answers here says that you can read and write to a socket at the same time as long as reading from the socket is done on a separate thread.
Here is my client application:
public class Client {
Socket socket;
public static void main(String[] args) {
new Client();
}
public Client() {
try {
socket = new Socket("localhost", 4444);
new Thread() {
#Override
public void run() { //read from the input stream
try(
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
) {
String line;
while( (line = in.readLine()) != null ) {
System.out.println("Server said: " + line);
}
} catch(IOException e) {
}
}
}.start();
//write to output stream
try(
PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
Scanner userInput = new Scanner(System.in);
){
System.out.println("Enter Something: ");
if(userInput.hasNextLine()) {
out.println(userInput.nextLine());
}
} catch (IOException e) {
}
} catch(IOException e) {
}
}
}
And my server application:
public class Server {
ServerSocket ss;
public static void main(String[] args) {
new Server();
}
public Server() {
System.out.println("Server Running...");
try {
ss = new ServerSocket(4444);
while(true) {
Socket socket = ss.accept();
new Thread() { //create new thread connection to client
#Override
public void run() {
new Thread() { //thread that reads inputstream
#Override
public void run() {
try(
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
) {
String line;
while( (line = in.readLine()) != null ) {
System.out.println("Client said: " + line);
//The problem seems to lie here.
}
} catch(IOException e) {
}
}
}.start();
//write to outputstream
try (
PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
) {
String sendToClient = "Hey, my name is Server007 B)";
out.println(sendToClient);
} catch(IOException e) {
}
}
}.start();
}
} catch (IOException e) {}
}
}
I will run the server, then run the client, on the client side the output is
Server said: Hey, my name is Server007
Enter something:
Hello! <- enter anything
but the server does not print 'Client said: Hello!' like I expected it to. I hope I made my problem clear enough, thanks.
Ok, so I figured it out, I will answer my own question in case anyone makes the same mistake. The PrintWriter constructor should be this:
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
Not this:
PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
Alternatively, I could have done this:
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
I must have just gotten confused between BufferedWriter and PrintWriter :P

Server is not sending back an acknowledgment to Client

I have my server code below over here:
public void startServer() {
ServerSocket listener = selectUnusedPortFromRange(1024, 65535);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
String command = null;
while (true) {
Socket socket = listener.accept();
System.out.println("Got a connection from: " + socket.getLocalPort());
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
command = in.readLine();
System.out.println("GOT HERE"); //Not being printed out
if (command != null && !"".equals(command)) {
if ("connection".equals(command)) {
Writer writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
writer.write("success\n");
writer.flush();
}
}
}
}
}
}
t.start();
}
This is my client side:
public void makeConnection() {
try {
Socket socket = new Socket(IP, PORT);
Writer writer = new PrintWriter(socket.getOutputStream(), true);
writer.write("connection\n");
BufferedReader socketRead = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str;
while ((str = socketRead.readLine()) != null) {
if ("success".equals(str)) {
System.out.println("Successfully saved all hosts to: " + listOfHosts.get(i));
socketRead.close();
socket.close();
iStream.close();
writer.close();
}
}
}catch (Exception e) {
System.out.println(e.getMessage());
}
}
On the client side after I create my socket to the connect to the server I write "connection" into the outputStream of the socket and wait for an acknowledgement back from the server saying success. For some reason the connection is not being made to the server. In the server System.out.println("Got a connection from: " + socket.getLocalPort()); this line is not being printed out.
Is there something wrong that I am doing. I can't spot it. And I am not getting an exception thrown when I try to connect to my server.
1) Make sure you use the same port for both the Client and Server. They must communicate over the same port. It seems you may be using different ports currently.
2) Make sure you actually start your server thread. As-is in your code above, you make a new Thread, but never start it. t.start() must be called somewhere.
3) If this is on your local machine, you may be better off using localhost instead of the actual IP address. Firewalls might treat your external IP differently.
4) Terminate your messages with a newline character, such as \n, so that your BufferedReader can use it's readLine() method. For good measure, also follow-up by flushing the writer's buffer, just in case the newline character didn't trigger that. writer.flush();
And lastly, make sure you terminate the JVM before trying to run your code again. Your code has not shutdown mechanism to un-bind the server from the port... so you may get an exception thrown telling you the port and/or address are already in use. If that happens, either change ports, or kill the java process running in the background.
Here is your code, slightly modified to run on my system. It's working as you might expect it to. I tried to change as little as possible just to get it working on my system. One note is, I hard-coded the port number into the server and client - that's not required, it was just convenient for me to test with:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
public class Test {
public static void main(String[] args) throws IOException {
Test test = new Test();
test.startServer();
test.makeConnection();
}
public void startServer() throws IOException {
final ServerSocket listener = new ServerSocket(60001);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
String command = null;
while (true) {
Socket socket = listener.accept();
System.out.println("Got a connection from: " + socket.getLocalPort());
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
command = in.readLine();
System.out.println("GOT HERE");
if (command != null && !"".equals(command)) {
if ("connection".equals(command)) {
Writer writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
writer.write("success\n");
writer.flush();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
t.start();
}
public void makeConnection() {
System.out.println("Making Connection");;
try {
Socket socket = new Socket("localhost", 60001);
Writer writer = new PrintWriter(socket.getOutputStream(), true);
writer.write("connection\n");
writer.flush();
BufferedReader socketRead = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str;
while ((str = socketRead.readLine()) != null) {
if ("success".equals(str)) {
System.out.println("Successfully saved all hosts to: "); //+ listOfHosts.get(i));
socketRead.close();
socket.close();
//iStream.close();
writer.close();
}
}
}catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
I was facing the exact same issue. I overcame it by using an ACK mechanism (Wasn't my idea, it was suggested to me). The idea is that client would make a request to server and keep the socket connection alive (and the ouput stream open) till server responds back an agreed ACK message over the same channel. Once the client receives the ACK message, only then it would close the connection.
Below is the code for Server :-
final ServerSocket listener = new ServerSocket(11111);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
String command = null;
while (true) {
System.out.println("About to accept");
Socket socket = listener.accept();
System.out.println("Got a connection from: " + socket.getLocalPort());
DataInputStream inputStream = new DataInputStream(socket.getInputStream());
StringBuilder str = new StringBuilder(inputStream.readUTF());
//command = in.readLine();
System.out.println("GOT HERE. Msg received : "+str);
if (str != null && !"".equals(str.toString())) {
command = str.toString();
if ("connection".equals(command)) {
System.out.println("Got connection message");
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
outputStream.writeUTF("connection");
outputStream.close();
}
}
inputStream.close();
System.out.println("Done");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
});
t.start();
}
Client :-
public void makeConnection() {
try {
System.out.println("In makeConnection");
Socket socket = new Socket("127.0.0.1", 11111);
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
outputStream.writeUTF("connection");
InputStream inputStream = socket.getInputStream();
DataInputStream dataInputStream = new DataInputStream(inputStream);
StringBuilder str;
do {
str = new StringBuilder(dataInputStream.readUTF());
} while (!str.toString().equals("connection"));
System.out.println("Successfully saved all hosts to: ");
outputStream.close();
dataInputStream.close();
socket.close();
outputStream.close();
}catch (Exception e) {
System.out.println(e.getMessage());
}
}
A call to start the proceedings :-
public void start() throws IOException, InterruptedException {
System.out.println("Starting server");
startServer();
Thread.sleep(1000);
System.out.println("Starting connection");
makeConnection();
}

Issues with Java Client<-->Server Socket

This is what I want to achieve:
There are client and server sockets. The client socket will send a message to the server (for instance "add:2:3" to add 2 and 3, etc). The server should response with an answer. When the answer arrives, the client can send additional message (like "subtract:5:8" to subtract 5 from 8), etc... Thus the client will send a message, then it will get a response, then it will send the next message and get a response, etc. Am sending the message from the command line.
This is what I have now but it is not working:
// Server code
public class MT extends Thread{
private Socket sock;
private BufferedReader rd;
private OutputStreamWriter wr;
private Client client;
public MT(Socket sock) throws IOException {
this.sock= sock;
rd = new BufferedReader(new InputStreamReader(sock.getInputStream()));
wr = new OutputStreamWriter(sock.getOutputStream());
wr.write("You are welcome" + "\n");
wr.flush();
}
public void run(){
try{
while(true){
String command = reader.readLine();
// Will process data here and then send results to client
// At the moment i just want to send the message back to client
wr.write(command + "\n"); // send results to client
}
}
}
}catch(IOException ex){
System.err.println("Problem reading data from client");
}
}
}
public class MyServio {
public static void main(String[] args) {
try(ServerSocket server = new ServerSocket()){
server.bind(new InetSocketAddress("0.0.0.0", 4444));
System.out.println("Listening...");
try{
while(true){
Socket con = server.accept();
Thread a = new MT(con);
a.start();
}
}catch(IOException ex){
System.err.println("Problem...");
}
}catch(IOException ex){
System.err.println("Server Issues");
}
}
}
// Client
For the client I decided to use two threads to read and write to the server
public class MyRead extends Thread{
private BufferedReader r;
public ReadFromServer(BufferedReader r){
this.r = r;
}
#Override
public void run() {
StringBuilder m = new StringBuilder();
try {
while(true){
message.append(r.readLine());
System.out.println(m);
}
} catch (IOException e) {
System.out.println("Problem in MyRead");
e.printStackTrace();
}
}
}
public class MyWrite extends Thread{
private OutputStreamWriter w;
Scanner sc;
public WriteToServer(OutputStreamWriter w){
this.w = w;
sc = new Scanner(System.in);
}
#Override
public void run() {
try {
while(true){
System.out.print("Type message: ");
String msg = sc.nextLine();
w.write(msg + "\n");
w.flush();
}
} catch (IOException e) {
System.out.println("Problem in MyWrite");
e.printStackTrace();
}
}
}
public class CSock {
private OutputStreamWriter w;
private BufferedReader r;
public ClientSocket() {}
public void do(){
InetAddress ad = null;
try {
ad = InetAddress.getByName("127.0.0.1");
} catch (UnknownHostException e) {
System.err.println("Error InetAddress");
}
try (Socket s = new Socket(addr, PORT)) {
System.out.println("Server connecting...");
StringBuilder message = new StringBuilder();
r = new BufferedReader(new InputStreamReader(s.getInputStream()));
w = new OutputStreamWriter(s.getOutputStream());
message.append(r.readLine()); // reads the welcome message from server
System.out.println(message);
// I start the read and write threads so that the client can read and write message to the server
ReadFromServer rd = new ReadFromServer(r);
WriteToServer wt = new WriteToServer(w);
rd.start();
wt.start();
} catch (IOException ex) {
System.err.println("problem connecting to server");
}
}
}
public class Main {
public static void main(String[] args){
ClientSocket clientSocket = new ClientSocket();
clientSocket.do();
}
}
I start the server first, and then I start the client, but the client gives an exception:
Problem in MyRead
java.net.SocketException: socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:170)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at model.ReadFromServer.run(ReadFromServer.java:31)
The last line in the exception indicates that message.append(reader.readLine()); in the code is the problem. I don't close sockets or input stream or output stream anywhere in my code, yet I get this exception.
Also get similar socket closed exception in the MyWrite class in the run() method in the following line writer.flush();
In the client on this line
try (Socket s = new Socket(addr, PORT)) {
You're telling the jvm that it should close the socket after executing the try statement.
This line is creating a reader from the output stream of the socket.
r = new BufferedReader(new InputStreamReader(s.getInputStream()));
And this is creating a functionality that read from server.
ReadFromServer rd = new ReadFromServer(r);
ReadFromServer is a thread, and it's free to execute after the try-catch statement has finished. So when it execute reader.readLine() the socket is closed.
You closed the socket and then continued to use it. The try-with-resource statement closed the socket; the two threads you started continued to use it.

Java BufferedWriter when connected to server - null pointer exception - chat app

It's a simple chat app. Server and client as separately app.
Connection between server and client works fine. I have a problem when i'm trying to send String from Client by BufferedWriter to Server BufferedReader. I have null pointer exception.
And can you tell me that is everything fine with threads logic in this app ?
Server app
public class Server {
private int port = 5000;
private ServerSocket server = null;
private Socket socket = null;
private InputStreamReader isr = null;
private OutputStreamWriter osw = null;
private BufferedReader br = null;
private BufferedWriter bw = null;
private Chat chat;
private String message;
private int bOffset = 10;
private JFrame mainFrame;
private JPanel mainPanel;
private JPanel boxPanel;
private JLabel boxTitleLabel;
private JTextArea incomingMessagesJTextArea;
private JTextField messageWritten;
private JButton sendServerButton;
public static void main(String[] args){
System.out.println("Server is running");
new Server().createGUI(); //some swing GUI things
new Server().createServerConnection();
}
public void createServerConnection(){
try {
/** Create socket for communication between apps */
server = new ServerSocket(port);
socket = server.accept();
System.out.println("Server accept client: OK");
/** Create output writers */
osw = new OutputStreamWriter(socket.getOutputStream());
bw = new BufferedWriter(osw);
/** Create inputs readers */
isr = new InputStreamReader(socket.getInputStream()); //data in bytes format
br = new BufferedReader(isr); //data in character format
} catch (IOException e) {
System.out.println("Server Error createServerConnection(): " +e.getMessage());
}
/** Create new thread for read server-input data */
new Thread(new Runnable() {
public void run() {
System.out.println("Server Thread - running");
while (true) {
try {
String message = br.readLine();
System.out.println(message);
} catch (IOException e) {
System.out.println("Server Error createServerConnection() -> new Thread: " +e.getMessage());
}
}
}
}
).start();
}}
Client app
public class Client {
private int port = 5000;
private Socket socket = null;
private InputStreamReader isr = null;
private OutputStreamWriter osw = null;
private BufferedReader br = null;
private BufferedWriter bw = null;
private String message;
private int bOffset = 10;
private JFrame mainFrame;
private JPanel mainPanel;
private JPanel boxPanel;
private JLabel boxTitleLabel;
private JTextArea incomingMessagesJTextArea;
private JTextField messageWritten;
private JButton sendServerButton;
public static void main(String[] args){
System.out.println("Client is running");
new Client().createGUI(); //some swing GUI things
new Client().createConnectionWithServer();
new Client().sendTextToServer();
}
public void sendTextToServer(){
try {
message = "test";
bw.write(message); //null pointer exception
bw.write('\n');
bw.flush();
} catch(Exception ex) {
ex.printStackTrace();
}
}
public void createConnectionWithServer(){
try {
/** Create socket for communication between apps */
socket = new Socket("localhost", port);
/** Create inputs readers */
isr = new InputStreamReader(socket.getInputStream()); //data in bytes format
br = new BufferedReader(isr); //data in characters format
/** Create output writers */
osw = new OutputStreamWriter(socket.getOutputStream());
bw = new BufferedWriter(osw);
} catch (IOException e) {
System.out.println("Server Error createConnectionWithServer(): " +e.getMessage());
}
/** Create new thread for read client-input data */
new Thread(new Runnable() {
public void run() {
System.out.println("Client Thread - running");
while (true) {
try {
message = br.readLine();
System.out.println(message);
} catch (IOException e) {
System.out.println("Client Error createServerConnection() -> new Thread: " +e.getMessage());
}
}
}
}
).start();
}}
Change your main method to create a unique instance of your Client class:
public static void main(String[] args){
Client client = new Client();
System.out.println("Client is running");
client.createGUI(); //some swing GUI things
client.createConnectionWithServer();
client.sendTextToServer();
}
You were creating a new instance of the Client class everytime you called the "new" statement. Doing so the variable were initialized in the fist instance, making impossible for the other one to acces the initialized variable (throwing NullPointerException)

Java gui, Client issue when trying to convert into gui

I have made a Client/Server programme in java, I have gotten it to work using the cmd perfectly as i want, now i am trying to convert the client side of the code into GUI, however i am having trouble with printing the client msg and reading the client input from the text fields and the server msg, here is what I have done so far, i get no errors when compiling but the gui it self doesn't run, any help is appreciated.
Here is the Client code:
import java.net.*;
import java.io.*;
import java.awt.*;
import java.util.Scanner;
import javax.swing.*;
public class TcpClient
{
public static void main(String[] args)
{
try
{
new TcpClient().start();
}
catch(Exception e)
{
System.out.println("Major Error" + e.getMessage());
e.printStackTrace();
}
}
public void start() throws IOException
{
JFrame build = new JFrame("Client");
JTextField serv = new JTextField();
JTextField clie = new JTextField();
build.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
serv.setBounds(50,210,300,50);
build.add(serv);
clie.setBounds(350,210,300,50);
build.add(clie);
//=====================================================================
Socket clientSocket = null;
InetAddress hostA = null;
PrintWriter clientOutput = null;
BufferedReader clientInput = null;
BufferedReader standardInput = null;
try
{
hostA = InetAddress.getLocalHost();
clientSocket = new Socket(hostA.getHostName(), 5600);
clientInput = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
clientOutput = new PrintWriter(clientSocket.getOutputStream(), true);
standardInput = new BufferedReader(new InputStreamReader(System.in));
String serverMsg, clientMsg;
//read from a socket and respond back to server
while((serverMsg = clientInput.readLine()) != null)
{
serv.setText("Server Saying - " + serverMsg);
if(serverMsg.equals("exit"))
break;
clientMsg = standardInput.readLine();
if(clientMsg != null)
{
clie.setText("Client Saying - " + clientMsg);
clientOutput.println(clientMsg);
}
}
}
catch(UnknownHostException e)
{
System.exit(1);
}
catch(IOException e)
{
System.exit(1);
}
finally
{
//clean up time
clientOutput.close();
clientInput.close();
standardInput.close();
clientSocket.close();
}
//=====================================================================
build.setLayout(null);
build.setSize(700,600);
build.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
build.setVisible(true);
build.setResizable(false);
}
}
As mentioned in the comments you should study multithreading and especially the EDT
What is happening right now is that your code and your GUI and preventing each other from working properly. By having your GUI run on the EDT your application can run without holding back the GUI. When the application has changes to report that are relevant for your GUI you can just inform the EDT when the time comes.

Categories