Getting caught Button in netbeans [duplicate] - java

I'm doing a client/server program in Java (including a GUI).
I've got the following code in the client:
public class SBListener implements ActionListener{
public void actionPerformed(ActionEvent e){
try{
outToServer.writeUTF(usn.getText().trim());
System.out.println("sent username to server");
playerExists = inToClient.readBoolean();
System.out.println("past getting player");
System.out.println("player exists = " + playerExists);
}catch(IOException a){
System.err.println(a);
}
if(playerExists == false){
JButton submitInfo = new JButton("submit info");
submitInfo.addActionListener(new SBNewInfoListener());
init.add(new JLabel(""));//dummy element to get the right alignment
init.add(new JLabel("First Name:"));
init.add(fn);
init.add(new JLabel("Last Name:"));
init.add(ln);
init.add(submitInfo);
add(init, BorderLayout.WEST);
init.setVisible(true);
init.revalidate();
init.repaint();
}
}
}
And the following code in the Server:
String username = inp.readUTF();
System.out.println(username);
out.writeBoolean(false);
System.out.println("wrote boolean, waiting for fn/ln/un");
fn = inp.readUTF();
System.out.println("got fn");
ln = inp.readUTF();
un = inp.readUTF();
But when the button that calls SBListener is clicked, the program freezes when it gets to the point where the Server is waiting for fn/ln/username. I added a bunch of system.out statements for debugging and I get up to the one that says "wrote boolean, waiting for fn/ln/un".
Basically, I'm trying to update the screen after the Server returns a false value. Specifically, I want to add two text fields for first & last name. I then want to send those values to the server.
Can anyone tell me how to fix this? Thanks in advance for any help!

Don't execute client/server code in an ActionListener. This will cause the Event Dispatch Thread to block while waiting for a response from the server. When EDT is blocked the whole GUI freezes.
Read the section from the Swing tutorial on Concurrency for more information. You need so use a separate Thread for the client/server code. Or you can use a SwingWorker as discussed in the tutorial.

My guess is that outToServer isn't being flushed. I would guess (although I can't tell from your sample code) that outToServer is a DataOutputStream. You need to call .flush to get the data out of the buffer and onto the wire.
Try this:
outToServer.writeUTF(usn.getText().trim());
outToServer.flush();

Related

The String after \n is not being displayed at all in the System output

So, I'm making a simple Server-client program using TCP as part of my college assignment. I've already created one before using UDP and just have to redo it using TCP. However, I came across something funny while coding. Apparently, Strings I'd send out from the server that contains a \n will only display the part of the String before the \n. All the other substring that follows after \n will not be displayed. I'm sort of puzzled by this. Maybe it might have something to do with my code for sending it?
The code below is from the server side.
P.S. I've tried researching a bit about this, and I couldn't really find anything concerning my issue. I've tried using "%n" because I saw it was suggested in a few forums, but that didn't work.
if(clientMessage.equals("1234"))
{
SendMessage(incoming, "Welcome.\nMenu:\n1. Check balance\n2. Deposit\n3. Withdraw\n4. Quit");
}
public static void SendMessage(Socket incoming, String message){
//9. Initialize String to send to client
//BufferedReader output = new BufferedReader(new InputStreamReader(System.in));
String serverMessage;
try {
serverMessage = message;
//10. Initialize PrintStream using getOutputStream() method of
//Socket
PrintStream send = new PrintStream(incoming.getOutputStream());
//11. Use println() method of PrintSteam to send data to client
send.println(serverMessage);
} catch (IOException ex) {
Logger.getLogger(ATMTCPServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
So, in the end I found the mistake I made from a friend of mine who pointed it out. Apparently, the mistake was in the client side. I didn't know that BufferedReader.readLine() would only read one line. So, that was why the substring after \n wasn't displaying. Afterwards, I came across a few other problems, but with the help of my friend, I eventually solved the problems and finished my assignment. Thank you to everyone who gave their comments!
P.S. I'll post the code of what I did to solve the problem below. The code below is from the client side. I didn't have to change anything on the server side.
serverMessage = incoming.readLine();
String[] messages = serverMessage.split("----");
for(int i = 0; i < messages.length; i++){
if(choice.equals("2") || choice.equals("3"))
{
System.out.print(messages[i]);
}
else
{
System.out.println(messages[i]);
}
}

Java server to handle multi-clients simultaneously

I am new to java server and client. I want to make a multi-client server. After making server code ready to accept more than one client it is like this :
Server code :
public class Server {
int clientNumber = 1;
ServerSocket mServer = new ServerSocket(9090);
try {
while (true) {
new TheServer(mServer.accept(), clientNumber++).start();
}
} finally {
mServer.close();
}
}
private static class TheServer extends Thread {
private Socket client;
private int clientNumber;
public TheServer(Socket client, int clientNumber) {
this.client = client;
this.clientNumber = clientNumber;
}
public void run() {
try {
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
dos.writeUTF(numberString);
while (true) {
String message = br.readLine();
dos.writeUTF(message);
}
} catch (IOException e) { }
}
}
The clients are added to the server as I expect.
If I have one client, the --- dos.writeUTF(message); --- give the desired result inside client console, so in server console I write down (A) and press enter, then the (A) is printed inside #1 Client, then I write down (B) in server console and press enter, then the (B) is printed inside #1 Client, it seems good.
But if the second client join the server, the result inside both clients console is hold for one time press and is fired on second enter press. To simplify : Inside server console I press (A) and press enter, nothing is happening on clients consoles, then I press (B) inside server console again, and now the first message (A) and second message (B) are printed one (A) inside #1 Client and one (B) inside #2 Client and this is not the behavior that I expect.
What I expect: When 2 Clients exist and server send message (A), I need all Clients (here there are 2 clients) get the message together. Imagine you are playing a game online, If I have a character (like a ball) and I move it inside a game field, all the other players have to see my character moving. I wish I was clear.
I think I have to make an array to keep the clients and send message to that array maybe...
So how can I solve it. If the client code is needed please tell me.
Look into something called the Publish-Subscribe pattern, also known as the Observer pattern, here is an example:
https://www.journaldev.com/1739/observer-design-pattern-in-java

Make socket wait for input from JTextArea

I am trying to learn a bit more about networking, sockets, udp etc..
// main method:
Socket clientSocket = new Socket("localhost", 10007);
PrintWriter clientSocketOutputStream = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader clientSocketInputStream = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
Scanner userInputReader = new Scanner(System.in);
String providedInput;
while ((providedInput = userInputReader.nextLine()) != null) {
clientSocketOutputStream.println(providedInput);
displayOnConsole("You have provided text: " + providedInput);
String responseFromTheServer = clientSocketInputStream.readLine();
System.out.println("Server has responded: " + responseFromTheServer);
System.out.println(waitingForInputText);
}
// rest of the code...
So this little code I have works well. ( I have a ServerSocket which runs fine on localhost ). However now I am trying to do this by GUI, not by commandline.
I have a simple JTextArea, and a JButton. I am stuck at:
while ((providedInput = userInputReader.nextLine()) != null)
How can I invoke the clientSocketOutputStream, everytime I hit the Jbutton and print the text from the JTextArea?
Shall I put a dead while(true) loop just to make sure the socket is waiting? Something tells me there must be another way.
Just put a listener on the the text area to detect when the content changes and then send whatever you like onto the output stream based on the change made.
In general a text area doesn't map well to this though as a text area you can edit anywhere, you are probably better having a read only text area to display the history - and then having a single text entry box (or a smaller text area) and a button that you press to send everything in the smaller box on the screen out on the stream, append the sent text to the end of the history, and then wipe the smaller box.
You can also add an event on a key press (for example the return key) to trigger the send-and-move-to-history process.

ObjectInputStream - How to wait for new data?

I've got a client-server app I'm making and I'm having a bit of trouble when reading objects on the server.
After my server connects to a client socket, I build object input and output streams and pass them along to my service() method. In there, I'm supposed to handle different kinds of messages from the client. I can get a message from the client (that is, a Message object, of my design) just fine. But of course, what I want to do is have a loop so I can get a message, process it, and respond back.
So far, my code only works for a single message. When I added my loop, what happened was on every iteration, my server just kept reading the same message over and over again before my client got a chance to send a new message over the socket (I think this is what's happening, at least).
So what I really need to do is figure out how to make my service() method wait for new input. Any ideas? Or am I approaching this wrong? Do I need to create a new OIS on every iteration or...? Some code:
public void service(ObjectInputStream input, ObjectOutputStream output) throws IOException, Exception {
_shouldService = true;
while (_shouldService) {
// It just keeps reading the same message over and over
// I need it to wait here until the client sends a new message
// Unless I'm just approaching this all wrong!
NetworkMessage message = (NetworkMessage) input.readObject();
NetworkMessageHeader header = message.getHeader();
String headerType = header.getType();
if (headerType.equals(NetworkMessageHeader.NetworkMessageHeaderTypeConnect)) {
doLoginForMessage(message, output);
} else if (headerType.equals(NetworkMessageHeader.NetworkMessageHeaderTypeFiles)) {
doFilesList(message, output);
} else {
System.out.println("Unrecognized header type: " + headerType);
}
}
}
The ObjectOutputStream caches object representations and will not detect if you are resending the same instance over and over again from the client side, but with changes in it. If this is your scenario you need to call reset on the stream before each send.
NetworkMessage message = new NetworkMessage();
for(;;) {
message.setProperty(whatever);
oos.reset();
oos.writeObject(message);
}

Question with sending object over java sockets

So I have been working on a 2 player Tic-Tac-Toe game in java that utilizes sockets. All of the socket stuff is working, and I am sending data back and forth successfully between 2 clients and a server.
I have the following classes: Requester, Provider, and TBoard (which extends Serializable).
In the Requester (client) class, I instantiate an object of TBoard (TBoard board = new TBoard()).
I then send that object through the socket to my two clients, via an output stream.
The error I am getting is on the client-side, and it is: Exception in thread "main" java.lang.ClassCastException: java.lang.String
That's happening with:
board = (TBoard) in.readObject(); in:
do {
try {
board = (TBoard) in.readObject();
System.out.println(board.print_board());
} catch (ClassNotFoundException classNot) {
System.err.println("data received in unknown format");
}
My print_board() method in the TBoard class is meant to return a 2d array, but for right now (simplification purposes), I have the method returning the string "Hello"...
Does anyone know why this may be happening? I didn't want to bombard you all with code, but please let me know if posting any more may be helpful...
Thanks!
UPDATE:
Here is what I have going on (in more detail) with my Provider (server) class:
// 1. creating a server socket
providerSocket = new ServerSocket(20092);
// 2. Wait for connection
System.out.println("Waiting for connection...");
connection1 = providerSocket.accept();
System.out.println("Connection received from Player 1 " +
connection1.getInetAddress().getHostName());
connection2 = providerSocket.accept();
System.out.println("Connection received from Player 2 " + connection2.getInetAddress().getHostName());
// 3. get Input and Output streams
out = new ObjectOutputStream(connection1.getOutputStream());
out2 = new ObjectOutputStream(connection2.getOutputStream());
in = new ObjectInputStream(connection1.getInputStream());
out.writeObject("Player 1 has been connected successfully.");
in2 = new ObjectInputStream(connection2.getInputStream());
out2.writeObject("Player 2 has been connected successfully.");
out.flush();
out2.flush();
out.writeObject(board);
out2.writeObject(board);
So I am indeed sending a String in the streams before sending the last object (board). However, I am flushing out the streams beforehand. I also tried reset()'s after the flushes, and it still gave me the IllegalCastException...
IIRC, the class mentioned in the Exception is the one that was actually found, so in the code you're showing, the error would have to be here:
board = (TBoard) in.readObject();
And a String object instead of a TBoard being read from the stream.
Edit:
So you are sending strings in addition to the data. There's your problem. You either have to stop sending those strings, or read them on the receiving side before reading the data. Calling flush() is irrelevant to that - it just ensures that the Strings that you have already written to the stream are in fact sent over the connection and not kept in a buffer.
To investigate, I think the easiest would be to visualize (log or debug) the actual class that result from in.readObject(). Sample code:
Object o = in.readObject();
System.out.println("Object of class " + o.getClass().getName() + " is " + o);
There are a couple of possibilities. Assuming you are using ObjectOutputStream (which I think you are), it's possible that the error is arising because you are not fully serializing each object. ObjectOutputStream will try and hold of resending if you don't reset the stream each time.
I would try the following:
1) make sure you flush() and close() the sockets at the appropriate times
2) try calling reset() after each object is sent.
3) check that you are sending and receiving the same object type, just in case.
best of luck.

Categories