Sorry, took too long and couldn't edit my last post. Update:
Ok, so this seems to be the issue: since read() blocks while it waits for input, when the client's receive() method is executed, all subsequent mouse clicks on the client "don't happen" until
after the client finishes receiving the data via the read() method. So when you click out of order, you are putting an extra event on the thread which doesn't get executed until after read() is done. What you really want to do is "throw away" the click and pretend it didn't happen at all. But I think you need to multi-thread your application. Hopefully someone else on Daniweb will verify this so that I'm not unintentionally leading you astray, but as of now, I believe this to be accurate.
This code will demonstrate to you what I'm talking about. If you look at the ClientTurn_flag variable, you'd expect that once you click (which calls receive() and sets ClientTurn_flag to false), the next time you clicked on the client's window, it should print out "wasn't client's turn". However, it doesn't do that, since the read() method is blocking the thread. In fact what *I think* happens is this. Lets say you run the program, then click:
1) Click client's window
-At this point ClientTurn_flag is true.
-client sends it's coordinates to the server.
-client calls receive method and waits for the server to take it's turn. The receive method calls read(), which blocks, so it just sits there waiting for the server to send it data. Now ClientTurn_flag is false, because it is set to false before read() is called.
-it is now the server's turn, and the server is sitting there waiting for you to click on it's window. ServerTurn_flag is true.
2) Click client's window again.
-Since the client is still sitting in the receive() method, which is blocking your thread, the mouse click doesn't happen yet. ClientTurn_flag is still false. Now you can basically think of your stack as looking like this:
first in line => receive() -> read()
next in line (behind both of the above) = mouse listener method.
3) Click server's window. Now you would wish that the client will receive the server's data and then ClientTurn_flag would be set to true. In fact, looking back at my logic, what I think is that after you click the server's window, the server calls its send method. Then the server calls receive() and waits for the client's turn and sets its ServerTurn_flag = false.
-Now, remember that read() was waiting on the client from part 2. Since the server just sent it's input, read() finishes in the client. At the end of read(), ClientTurn_flag = true. So now, in the client, since the next method call on the stack (from clicking on the window) was the mouse listener method, that mouse listener method gets called. But you never clicked anything while it was your turn! The click was done while it was the server's turn.
-After mouse listener method gets called, it calls send(), and it sends the coordinates of the mouse click
from when you clicked earlier to the server. This may not cause a problem if the server happens to be waiting to receive, but I'm pretty sure that if you had clicked the client more times, or switched around the ordering of clicking on client and server, it would. You don't want this to happen because the server should always be ready to receive when the client wants to send and vice versa.
Anyway, I spent a good bit of time attempting to figure out and then explain your problem, so I sincerely hope that it is correct. You can test my sample program to confirm that it appears to be correct.. for example, when you click the mouse over and over, you can tell that read() is blocking because the print statements get printed out much later in the program. I believe you can solve your problem by multi-threading your application so that every time a mouse is clicked, it checks (in a separate thread!) to see if it is that Client's/Server's turn, and if not, the method call just returns.
package game;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.swing.*;
public class Clientms2 extends JFrame implements MouseListener
{
private static final long serialVersionUID = 1L;
JFrame container;
static InetAddress address;
static Socket s;
static String host = "localhost";
static BufferedOutputStream bos;
static OutputStreamWriter osw;
static BufferedInputStream bis;
static InputStreamReader isr;
static int port = 5656;
static String message;
static boolean ClientTurn_flag = true;
//static MouseListener l;
static int tempx, tempy;
static int mouseX, mouseY;
static StringBuffer x, y;
public Clientms2()
{
super("Client 1: Player 1");
setSize(400, 400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setResizable(false);
addMouseListener(this);
try {
address = InetAddress.getByName(host);
s = new Socket(address, port);
} catch(Exception e){System.out.println("You fail at socket programs sucka!!!");}
}
public static void main(String args[])
{
Clientms2 client = new Clientms2();
client.setVisible(true);
}
@Override
public void mouseClicked(MouseEvent e)
{
if (ClientTurn_flag){
mouseX = e.getX();
mouseY = e.getY();
send(mouseX, mouseY);
System.out.println("End of client's turn, client waiting to receive.");
receive();
}else{
System.out.println("Wasn't clients turn");
}
}
public void receive()
{
System.out.println("Receive method called, all subsequent clicks on the client's window" +
"should now result in seeing 'wasn't client's turn'");
ClientTurn_flag = false;
try
{
do
{
bis = new BufferedInputStream(s.getInputStream());
isr = new InputStreamReader(bis, "US-ASCII");
} while(isr.ready() == true);
x = new StringBuffer();
y = new StringBuffer();
while((tempx = isr.read()) != 13)
x.append((char) tempx);
String str = x.toString();
mouseX = Integer.parseInt(str);
while((tempy = isr.read()) != 13)
y.append((char) tempy);
str = y.toString();
mouseY = Integer.parseInt(str);
ClientTurn_flag=true;
} catch (IOException e) { System.out.println("Error in client received"); }
System.out.println("Client finished receiving");
ClientTurn_flag= true;
}
private void send(int xcor, int ycor)
{
try
{
bos = new BufferedOutputStream(s.getOutputStream());
osw = new OutputStreamWriter(bos, "US-ASCII");
message = (Integer.toString(xcor)) + (char) 13;
osw.write(message);
osw.flush();
message = (Integer.toString(ycor)) + (char) 13;
osw.write(message);
osw.flush();
ClientTurn_flag = false;
} catch (IOException e) { e.printStackTrace(); }
System.out.println("Client finished sending");
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
}
package game;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.*;
import java.net.*;
import javax.swing.*;
public class Serverms2 extends JFrame implements MouseListener
{
private static final long serialVersionUID = 1L;
JFrame container;
static Socket s;
static ServerSocket ss;
static BufferedOutputStream bos;
static OutputStreamWriter osw;
static BufferedInputStream bis;
static InputStreamReader isr;
static StringBuffer x, y;
static int port = 5656;
static int ID, count = 0;
static int tempx, tempy;
static int mouseX, mouseY;
static String message;
static boolean ServerTurn_flag = false;
public Serverms2()
{
super("Server: Player 2");
setSize(400, 400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setResizable(false);
addMouseListener(this);
try {
ss = new ServerSocket(port);
} catch (IOException e1) { e1.printStackTrace(); }
}
public static void main(String args[])
{
Serverms2 server = new Serverms2();
server.setVisible(true);
try {
s = ss.accept();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
server.receive();
}
@Override
public void mouseClicked(MouseEvent e) {
if (ServerTurn_flag){
mouseX = e.getX();
mouseY = e.getY();
send(mouseX, mouseY);
receive();
} else{
System.out.println("Wasn't servers turn.");
}
}
public void receive() {
ServerTurn_flag = false;
try
{
bis = new BufferedInputStream(s.getInputStream());
isr = new InputStreamReader(bis, "US-ASCII");
x = new StringBuffer();
y = new StringBuffer();
while((tempx = isr.read()) != 13)
x.append((char) tempx);
String str = x.toString();
mouseX = Integer.parseInt(str);
while((tempy = isr.read()) != 13)
y.append((char) tempy);
str = y.toString();
mouseY = Integer.parseInt(str);
} catch (IOException e) {System.out.println("I hate it when this crap happens.."); }
System.out.println("Server done receiving.");
ServerTurn_flag = true;
}
private void send(int xcor, int ycor)
{
try
{
bos = new BufferedOutputStream(s.getOutputStream());
osw = new OutputStreamWriter(bos, "US-ASCII");
message = (Integer.toString(xcor)) + (char) 13;
osw.write(message);
osw.flush();
//System.out.println(message);
message = (Integer.toString(ycor)) + (char) 13;
osw.write(message);
osw.flush();
bos.flush();
//System.out.println(message);
} catch (IOException e) { e.printStackTrace(); }
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
}