0

i am creating a LAN game that accepts strings and parses them from structured english and displays them on a grid. i have created the server and client and it works but im having some issues. when i send a string it doesnt appear on the other machine right away. for some reason the string is only sent to the other machine once the other machine sends something over. i dont know why this happens. Could you please help me find out why it doesnt send straight away. Thanks

Server Code:

import java.awt.Point;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
public class studentServer{
static ServerSocket serverSocket;
static Socket socket;
static PrintWriter printWriter;
static BufferedReader bufferedReader;
static Thread thread;
Console console = new Console();


public ServerPlayergameMain gm;
    public static void main(String args[]) throws Exception{
}
public void run(String commandMessage){
    while(true){
        try{
            printWriter.println(commandMessage+"\n");
            String input = bufferedReader.readLine();//reads the input from textfield
            console.readLine("Client message: "+input);//Append to TextArea
        }catch(Exception e){}
    }
}
    public void serverStartActionPerformed() {
    System.out.println("Server has started!");
    try{
        serverSocket = new ServerSocket (8888); // socket for the server
        socket = serverSocket.accept(); // waiting for socket to accept client
        JOptionPane.showMessageDialog(null, "Your opponent has connected!", "Opponent Connection!", JOptionPane.INFORMATION_MESSAGE);
        gm = new ServerPlayergameMain();
        gm.setVisible(true);
        bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); // reads line from input streamer
        printWriter = new PrintWriter(socket.getOutputStream(),true);
    }catch(IOException | HeadlessException e){
        System.out.println("Server not running!"); //print message if server is not running
    }
}
}

Client Code:

import java.io.*;
import java.net.*;
import javax.swing.JOptionPane;
public class StudentClient {
static Socket socket;
static PrintWriter printWriter;
static BufferedReader bufferedReader;
static Thread thread;
Console console = new Console();


public ClientPlayergameMain gm;

public void Clients(String address) {
    try{
        socket=new Socket("localhost",8888);//Socket for client
        //below line reads input from InputStreamReader
        bufferedReader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
        //below line writes output to OutPutStream
        printWriter=new PrintWriter(socket.getOutputStream(),true);
        JOptionPane.showMessageDialog(null, "Connected to server successfully", "Success", JOptionPane.INFORMATION_MESSAGE);
        gm = new ClientPlayergameMain();
        gm.setVisible(true);
        System.out.println("Connected");//debug code
    }catch(Exception e){
       JOptionPane.showMessageDialog(null, "No Connection to server", "Error", JOptionPane.ERROR_MESSAGE);
        System.out.println("Not Connected");
    }    
}
public static void run(String commandMessage){
        while(true){
            try{
                printWriter.println(commandMessage+"\n");
                String input = bufferedReader.readLine();
                System.out.println("From server:" +input);
            }catch(Exception e) {}
        }
}
}

The code works but i dont know why there is a condition for the other machine to send something.

Thanks for your time.

Charles
  • 50,943
  • 13
  • 104
  • 142
Hesham A
  • 43
  • 9

3 Answers3

0

Have you tried printWriter.flush() after each write/print?

DJ.
  • 6,664
  • 1
  • 33
  • 48
  • 1
    Auto Flush is used while constructing printWriter object as passed second argument in constructor `printWriter=new PrintWriter(socket.getOutputStream(),true);`. Hence there is no need to call `flush()` manually. – Braj Mar 11 '14 at 20:15
  • i automatically call flush() like @Braj said. thanks for your help anyway. – Hesham A Mar 12 '14 at 19:45
0

A lot of compilation problems are there in you code. Some of the classes and objects are missing to resolve.

Still I have tried it to figure out the issue.

It may be the reasons:

  • sending new line character \n in printWriter.println(commandMessage+"\n"); statement, just remove \n.
  • client and server both are writing first in printWriter.println(commandMessage+"\n"); statement, make it last in anyone class

Here is the code:

StudentServer.java:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class StudentServer {
    static ServerSocket serverSocket;
    static Socket socket;
    static PrintWriter printWriter;
    static BufferedReader bufferedReader;
    static Thread thread;

    public static void main(String args[]) throws Exception {
        StudentServer studentServer = new StudentServer();
        studentServer.serverStartActionPerformed();
        studentServer.run("server");
    }

    public void run(String commandMessage) {
        if (true) {
            try {
                printWriter.println(commandMessage);
                String input = bufferedReader.readLine();// reads the input from textfield
                System.out.println("Client message: " + input);// Append to TextArea
            } catch (Exception e) {
            }
        }
    }

    public void serverStartActionPerformed() {
        System.out.println("Server has started!");
        try {
            serverSocket = new ServerSocket(8888); // socket for the server
            socket = serverSocket.accept(); // waiting for socket to accept client
            bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); // reads
                                                                                                 // line
                                                                                                 // from
                                                                                                 // input
                                                                                                 // streamer
            printWriter = new PrintWriter(socket.getOutputStream(), true);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Server not running!"); // print message if server is not running
        }
    }
}

StudentClient.java:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class StudentClient {
    static Socket socket;
    static PrintWriter printWriter;
    static BufferedReader bufferedReader;
    static Thread thread;

    public void clients() {
        try {
            socket = new Socket("localhost", 8888);// Socket for client
            // below line reads input from InputStreamReader
            bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            // below line writes output to OutPutStream
            printWriter = new PrintWriter(socket.getOutputStream(), true);
            System.out.println("Connected");// debug code
        } catch (Exception e) {
            System.out.println("Not Connected");
        }
    }

    public void run(String commandMessage) {
        if (true) {
            try {
                String input = bufferedReader.readLine();
                System.out.println("From server:" + input);
                printWriter.println(commandMessage);
            } catch (Exception e) {
            }
        }
    }

    public static void main(String args[]) throws Exception {
        StudentClient studentClient = new StudentClient();
        studentClient.clients();
        studentClient.run("client");
    }
}
Braj
  • 46,415
  • 5
  • 60
  • 76
  • sorry but that doesnt work. when i put the "printWriter.println(commandMessage);" at the end it doesnt even send the message over. i dont think that is the problem. do you think it might be an issue with the bufferedReader? – Hesham A Mar 12 '14 at 19:59
  • Have you tried all the things that I have mentioned in my answer because its working for me? Let me post my files. – Braj Mar 12 '14 at 20:00
  • I have updated my answer. Please try it. Replace `if` condition with `while` in `run` method. Let me know if still there is any issue in my code. – Braj Mar 12 '14 at 20:04
  • im not sure what you mean? what shall i do? shall i replace the while loop in the run method with an if statement? – Hesham A Mar 12 '14 at 21:59
  • Is the code working posted by me without any change? – Braj Mar 12 '14 at 22:03
  • I am really Sorry but I am not able to understand... Please explain. What is expected step by step? Response in terms of Server & Client meanwhile I am trying to understand it. – Braj Mar 12 '14 at 22:13
  • Here is my output in sequence: 1. Server has started! 2. Connected 3. From server:server 4. Client message:client . Server is connected to client as soon as client join the socket. first server writes some message to client that is read by client and client write back some message that is read by server. OK let me post you a swing chat application. I will come back in few minutes. – Braj Mar 12 '14 at 22:23
  • the code is working, but i cant test it because it closes all my open jFrames for some reason. the server and client connect but i cant test it because i cant send text over. im not sure how to test it. could you be kind enough to extend the code to allow simple string input from the console or whatever its called? – Hesham A Mar 12 '14 at 22:26
  • but to explain the current situation and what i want to achieve. right now there is a delay when the server sends a message to client and vice verse. the string that the server sends is delayed and only displayed once the client sends a message. i want to achieve a communication between the client and the server where whenever the client or server sends a message it is displayed automatically, and it doesnt need to wait for the other machine to send something. hope that helps – Hesham A Mar 12 '14 at 22:36
0

There are quite a few little problems, as Braj points out. The main one is in this sequence on your server side:

   serverSocket = new ServerSocket (8888); // socket for the server
   socket = serverSocket.accept(); // BLOCKS waiting for socket to accept client
   // ..
   printWriter = new PrintWriter(socket.getOutputStream(),true);

This means that printWriter, which you use to write to the client, doesn't even exist until after the server has listened for, blocked waiting on, and accepted a connection from the client.

If you want the connection to be opened for reading and writing without seeming to send anything from the client, send a handshake from the client. You could copy SMTP, and use HELO <myname>. That even tells the server who's calling.

Update after further reading:

I've always done like you have, and used the implicit connect that happens when you use getOutputStream() on the client side. However, Socket does allow you to connect an existing socket manually, using Socket#connect(). Try that, maybe it will work better than a handshake, for you.

Paul Hicks
  • 13,289
  • 5
  • 51
  • 78