Archive for category Java

Java ServerSocket Close Accept() Throws Socket Closed Exception

So, I am creating a simple multi-threaded game server (generic client/server) app in Java. I ran into a problem with threading that I thought I would post about. It may help someone else save a few hours of their time.

I have a class called TCPServer which implements Runnable (used for Java threading) and serves as a socket listener for my server. It waits for connections and then adds those connections to a connection manager. Each connection starts its own thread. The thing about threads is that they are easy to make, but melt my mind when it comes to managing them correctly. I thought I had a good handle on it. I did actually, but it made me think I was crazy for a few hours none-the-less.

So in my main class I have a command that starts the TCPServer. It creates a new one and then in the constructor, I start the thread. Well, as you may know, Thread.stop() is a deprecated and shunned method. Don't use it. I thought I was going to have to, but I forced myself to find the real reason for my issue.

Let me discuss the issue. The thread starts and a while loop checks a variable called receivingConnections. Theoretically, if this variable is set to false, it should break out of the thread and everything should be hunky dorey. I created a stop method which set this variable to false and then closed the ServerSocket.

Here's where the fun began. When I issued the command to execute the stop method, I kept getting a "socket closed" exception. This was being caught on the accept() method of ServerSocket. I couldn'tĀ figure out why it was throwing the exception. The socket was closed, true... but why did it keep trying to use the accept() method after the socket is closed.

I thought that it was due to the receivingConnections variable not being volatile. I changed this but still ran into the same issue.

The answer is rather crazy. You see, ServerSocket's accept() method just waits for a connection. The while loop that it was in was just stalled waiting on a new connection. Closing the socket triggered the exception. Even though right before the accept() method was called, I was checking if the socket was closed. My guess is that the accept() method simply starts its own infinite loop and waits on the new connection. As far as I can see, there's no way to break out of that.

The solution... set your flag variable to false. In my case it was the receivingConnections variable. Create a new client socket connection to the server and close it immediately. Then you can safely close the ServerSocket. This fools the accept() method, which forces an iteration of your while loop, which sees that your flag is now false, breaking out of the loop.

, ,

2 Comments

lwjgl.dll: Can’t load IA 32-bit .dll on a AMD 64-bit platform

If you encounter this error while trying to write a game on a Windows 64 bit system using Slick2d, I can give you some insight into how to fix the issue. I'd ran into this issue some time ago, but I don't remember if I posted about it or not. I solved the problem then by using a recompiled version of slick2d. It worked well, but I did something different this time around.

I downloaded the latest version of LWJGL and used it instead. The process of importing the libs is much the same except you use the new LWJGL and its natives instead of the ones included with slick2d. If you need help getting the imports correct, leave a comment and I'll go into it in more detail.

»crosslinked«

, ,

1 Comment

Marte Engine Define() and Check()

I'm not very fond of the way that Marte Engine's Input checking occurs. It simplifies things a bit in one area and complicates things in all other areas. The simplification comes from the fact that one can list all the keys for a given action in the listener definition (define("name", keys...), and that is pretty helpful.

However there's something I don't really care for when it comes to the way Marte Engine handles keyboard input, namely, it's too fast. The key repeat becomes an issue when working with things like menus.

Disclaimer: I'm far from being a Java or game development guru. I'm merely pointing out that I ran into this issue. There could very well be a work-around for this within the Marte engine itself. I ran into this problem while trying to implement a main menu for a test game I was working on. When I would push a button, the menu selection cursor would jump to the bottom of the menu, which isn't at all what I wanted it to do.

The believe the reason for this is that the input definitions one can make with a define() method are set to handle only KeyDown events, while I needed a KeyPressed event. Since I could find no other way to force it to use a keypress instead of a keydown, I decided to remove my input event definitions and use a standard check on the input to see if a certain button has been pressed (down and released). This solved my issue with the key events. Now my menu cursor performs as expected.

, , ,

No Comments

Marte Engine TextEntity setColor()

I've been focusing on learning Java game development over the last couple of weeks. I've found that lwjgl, Slick2d, and Marte Engine are great libraries to help with the basic game functionality. In fact, they take a lot of the work out of it and leave you to focus on the game design itself. For instance, the Marte engine comes with a great resource manager class that helps keep up with images, sounds, and spritesheets for your game. Marte also has some good classes which extend Slick2D's Entity class which can be very useful.

The one I'm going to focus on is TextEntity, which is great for adding text to the screen. However, I was unable to change the text color for the text directly using the setColor() method from the Entity class, which is inherited by TextEntity. There's not a lot of documentation for either Slick2D or Marte, so I wasn't exactly sure if I was missing something or if I had found a problem with the class.

Fixing the problem is rather simple. I created a new class called MyText and copied everything over from the TextEntity class. I could have extended it, but instead I wanted a new class which extends Entity directly. Then I changed the code in the render() method as such:

1
2
3
4
5
6
7
8
9
10
11
public void render(GameContainer container, Graphics g)	throws SlickException {
	if (font == null) {
		font = container.getDefaultFont();
		this.calculateHitBox();
	}
	g.setFont(font);
	if (text != null) {
		g.setColor(this.getColor());
		g.drawString(text, x, y);
        }
}

I then added a new constructor that takes a color as the fifth parameter:

1
2
3
4
5
6
public MyText(float x, float y, Font font, String text, Color color) {
	super(x,y);
	this.setColor(color);
	this.font = font;
	this.setText(text);
}

This gave me the functionality I was after. This change basically just sets the graphics object color property to the Entity's color property, which is exactly how I thought it should have worked to begin with.

If there's a better way to accomplish this, let me know. I'm only intermediate with Java.

No Comments

Adding Slick 2D and lwjgl to Eclipse Project

I spent some time today trying to get Slick and the light-weight java game library setup correctly in Eclipse. The tutorial I was watching was in Netbeans and I was very unfamiliar with adding libraries to a Java project in Eclipse (very familiar now). I'm going to go over how to do this as an overview, mainly just to remind me how to do it later hehe. It may also be of use to others who don't need a step by step picture guide of the process. So, here goes!

  1. Create a new project in Eclipse
  2. Right-click the project and choose New -> Folder (call it "lib")
  3. Right-click the lib folder and choose Import... then General -> File System
  4. Browse to your slick folder and choose the slick.jar and the lwjgl.jar files.
  5. Right-click on the project and choose Properties
  6. Choose "Java Build Path" and click the "Libraries" tab
  7. Click "Add Jars". It will show a tree of your project. Expand it till you see your lib folder. Expand it. Select the two jars (utilize shift for multiple selection). Click OK.
  8. Click OK again to go out to the workspace.
  9. Right-click on the lib folder and Import again. This time use "Archive File" instead of "File System". Click Next.
  10. Browse to your slick lib folder and find "natives-win32.jar". Click open.
  11. It will list some dlls on the right column. Make sure they are all checked and click finish.
  12. Repeat steps 9-11 and add the natives for mac and linux the same way if you want them.
  13. Now you need to add those natives to lwjgl. So...
  14. Right-click on the project and choose properties.
  15. In the Java Build Path -> Libraries tab, expand lwjgw.jar and click on Native library location.
  16. Click Edit. Click Workspace. Navigate to the lib folder, choose it, and click OK.
  17. NOW ALMOST THERE!
  18. Back in the Java Build Path -> Libraries, expand slick.jar. Click JavaDoc location.
  19. Click Edit. Set the javadoc location path to the location of the slick\javadoc folder.

Step 20... Add a class to your project and see if it will compile correctly. Here's an example for testing.

GameTest.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
 
public class Game extends BasicGame {
	public Game(String title) { super(title); }
 
	public static void main(String[] args) throws SlickException {
		AppGameContainer app = new AppGameContainer(new Game("Test Game"));
		app.start();
	}
 
	@Override
	public void render(GameContainer container, Graphics g)	throws SlickException {
		g.drawString("Hello, World!", 0, 100);
	}
 
	@Override
	public void init(GameContainer container) throws SlickException {
 
	}
 
	@Override
	public void update(GameContainer container, int delta) throws SlickException {
 
	}
}

, , , ,

2 Comments