Client & Server (first time need help) [FIXED]

I’ve never actually wrote a client & server in Java as a game yet, now i’m wanting to create and setup a client & server in Java so that I can do the following:

Send packets of TCP or UDP from server to client and vice versa. 0%?
Have a thread I guess? (never done this), but a constant game loop of transmitting packets back and forth. 50%
Being able to update the JFrame’s JPanel according to the data received from the server. 0%

Guess that’s it for now, really hope to get some feedback, I know how to setup a basic client & server to send data twice, once to the client, than back to the server, haven’t really tried implementing a thread yet.

Just got done fixing it, I just added another ‘while’ loop to send data back to the Server, now the client stays open and sending :slight_smile:

How to start threads:


new Thread() {
    {
        start();
    }
    
    public void run() {
        //initialize socket stuffs
        
        while(keepSending) {
            //send and receive
        }
        
        //close the socket
    }
};

Most simplistic way of doing client-server games is to start a new thread for each client on the server.

Here’s what I got for the Server so far, yet everytime I run it (it creates a new thread fine), but it keeps saying ‘Connection reset’, after a new client connects.


	// Constructor for the Server class.
	public Server() {
		running = true, keepSending = true;
		connect();
	}
	
	protected final void connect() {
		try {
			serverSocket = new ServerSocket(port);
			log(System.out, "Server listening on port: " + port + "...");
			new Thread() {
				{
					start();
				}

				public void run() {
					// Wait for client to connect on 4442
					try {
						clientSocket = serverSocket.accept();
						clientSocket.setSoLinger(true, MAX_PRIORITY);
						log(System.out, "Connected a new Client!");
						// Create a reader
						bufferedReader = new BufferedReader(
								new InputStreamReader(
										clientSocket.getInputStream()));
						// Get the client message
						while ((inputLine = bufferedReader.readLine()) != null)
							System.out.println(inputLine);
					} catch (SocketException e1) {
						log(System.err, "Client disconnected!");
					} catch (IOException e) {
						System.out.println(e);
					}
					// close the socket
					closeCons();
				}
			};
		} catch (IOException e) {
			log(System.err, e.getMessage());
		}
	}

	private static void closeCons() {
		try {
			serverSocket.close();
			clientSocket.close();
			bufferedReader.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

Here’s the output in the console after launching the client:

It might have something to do with the Client class, yet it’s still not sending the String?


	// Constructor for the Client class.
	public Client() {
		connect(port);
	}

	private void connect(int port2) {
		try {
			socket = new Socket("localhost", port2);
			log(System.out, "Client connected");
			log(System.out, socket);
			printWriter = new PrintWriter(socket.getOutputStream(), true);
			sendData("Hello Socket!");
			sendData("WOOOOOOOOOOOOO");
		} catch (SocketException e1) {
			log(System.err, "Client disconnected!??!");
		} catch (Exception e) {
			log(System.err, e.getMessage());
		}
	}

Both on the same ports, 4442, if anyone can see why it’s not working correctly please let me know.
I’ll continue to try and fix it, i’d like the Client not to disconnect.

Well if you didn’t suppress the SocketException, then you would find out why it closed :slight_smile:

Here’s the consoles outprint of the stacktrace:


java.net.SocketException: Connection reset
	at java.net.SocketInputStream.read(Unknown Source)
	at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
	at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
	at sun.nio.cs.StreamDecoder.read(Unknown Source)
	at java.io.InputStreamReader.read(Unknown Source)
	at java.io.BufferedReader.fill(Unknown Source)
	at java.io.BufferedReader.readLine(Unknown Source)
	at java.io.BufferedReader.readLine(Unknown Source)
	at server.util.connection.Server$1.run(Server.java:55)

And here’s line 55:


// Get the client message
	while ((inputLine = bufferedReader.readLine()) != null) { // line 55.
		System.out.println(inputLine);
	}

Do you get any errors on the client? Do you ever close the connection on the client? Does the client JVM terminate without you close()-ing the connection?

Client console after program launch:


Client connected
Socket[addr=localhost/127.0.0.1,port=4442,localport=57018]

Than it exits, might be because it’s being called upon by a batch file?


@echo off
@color 0a
@title Running: Client

:main
cls
java -Xmx800m -cp bin; server.util.connection.Client
pause
goto main

So, I start off by launching the Server in Eclipse, than I launch the Client via batch file, no exit called in either class.

Is it because the Client class has no active thread/loop?, just calls a simple try/catch.

In your client code, you only invoke connect(). Is there more code to this or does the main thread terminate after that?

If the main thread terminates: that is the reason you are seeing “connection reset”, because the process ended before it could tell the other side that the TCP connection should terminate.

Whole Client class (Minus the methods for custom System.out.print)


	// Main program launch point.
	public static void main(String[] args) {
		new Client();
	}

	// Constructor.
	public Client() {
		connect(port);
	}

	// First method called.
	private void connect(int port2) {
		try {
			socket = new Socket("localhost", port2);
			log(System.out, "Client connected");
			printWriter = new PrintWriter(socket.getOutputStream(), true);
			sendData("Hello Socket");
			sendData("WOOOOOOOOOOOOO");
			closeCons();
		} catch (SocketException e1) {
			log(System.err, "No Available Server launched on port: "+port2);
			System.exit(0);
		} catch (Exception e) {
			log(System.err, e.getMessage());
		}
	}

	// Method used to close connections.
	private void closeCons() {
		try {
			printWriter.close();
			socket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// Custom method used to send Data.
	private void sendData(String text) {
		if (printWriter != null) {
			printWriter.println(text);
		} else if (printWriter == null) {
			log(System.err, "PrintWriter == NULL!");
			return;
		}
	}

This is wierd…, why would the console be printing out that a connection from ‘activate.adobe.com’ was accepted before/instead of my Client?


Server listening on port: 4442...
Connection accepted from: activate.adobe.com
Hello Socket
WOOOOOOOOOOOOO

Used from:


clientSocket.getLocalAddress().getCanonicalHostName()

Oh! You close the connection after you are done with writing stuff into it :stuck_out_tongue:

activate.adobe.com resolves to 192.150.16.69, which is somehow your IP? That’s weird ;D

Could you help me ra4king lol, i’ve been swapping code, moving it, debugging for a few hours now e.e…

Server steps: launch, connect, receive, loop.

Client steps: launch, connect, send.

How can I get the client to constantly remain connected?
About the activate.adobe.com… I swear i’m infected by a virus from trying to download some free ‘Photoshop.exe’ e.e…

Note: I haven’t tested the code below.

Also, instead of writing a client to test your server, try to connect to it through telnet or something similar. That’s what I do :stuck_out_tongue:

I suggest you read about Sockets and Server/Client communications in general from google search-> http://www.oracle.com/technetwork/java/socket-140484.html

class TestServer implements Runnable {
 ServerSocket ss;

  // Constructor
 TestServer( int port ) {
  ss = new ServerSocket( port );
  Thread t = new Thread( this );
  t.start();
 }

  @Override
  public void Run() {
     while( true ) {
     Socket socket = ss.accept(); // blocking
     if (socket != null) new TestClient( socket );
     }
   }

  // Test starter
  public static void main(String[]  argv) {
   int port = 8080; // Default port

   if (argv.length > 0) port = Integer.parseInt( argv[1] );

   new TestServer( port );
  }


}
class TestClient implements Runnable {
 Socket socket;

  // Constructor
 TestClient( Socket socket ) {
 if (socket != null){
   this.socket = socket;
   Thread t = new Thread( this );
   t.start();
  }
 }

  @Override
   public void Run() {
    OutputStream = socket.getOutputStream();
    InputStream = socket.getInputStream();
    byte[] buffer = new byte[512];

    // Before listening for input, send the client a greeting.
    out.write( "Hello".getBytes() );

    while( true ) {
    int bytesRead = in.read( buffer ); // blocks
    if (bytesRead < 0) { // client disconnected
     socket.close();
     break;
     }

    if (bytesRead > 0) { // There's data to be read
      // do somethign with the data inside buffer
      
      // Send data back to client. ( Echo server )
      out.write( buffer );
    }

    }

  }
}

Thanks mate, got it all working now.
Think i’ll be implementing a GUI of somesort :slight_smile:

It’s best to specify a charset, specifically UTF-8, so do getBytes(“UTF-8”).

Nice that you got it working! :slight_smile: