Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
trex eaterofcadrs
Jun 17, 2005
My lack of understanding is only exceeded by my lack of concern.

ssergE posted:

Not necessarily a webapp, but mainly server-side apps that use things like queues, topics, persistence, etc.

Would I be correct in thinking that I need to concentrate on either Seam+JBossAS or Spring?

Either of those choices (Seam or Spring) would be good. I personally use Spring a lot and I like it, but maybe I'm just used to it.

Adbot
ADBOT LOVES YOU

Fruit Smoothies
Mar 28, 2004

The bat with a ZING
Not sure if this is the place for GWT discussion, but I figure I'll give it a whirl.

I'm new to Java, but familiar with pascal and PHP :cool:

I have a main google webapp class, and a secondary class, which handles all the XML getting. One function within this XML class has a callback which fires when the XML is received from the server.
I would like all this call-backing to be handled within the XML class, and for a function to be triggered within the main class when it's all done, so it can update the web GUI.
The XML get is async, so I can't feed the XML as a function result, and OO structure prevents the secondary class calling a function in primary. (right?)

In the world of windows GUI, the window would handle the event easily, but in this wilderness, I'm left stuck for ideas. Am I missing something blindingly obvious here?

Volguus
Mar 3, 2009

Fruit Smoothies posted:

Not sure if this is the place for GWT discussion, but I figure I'll give it a whirl.

I'm new to Java, but familiar with pascal and PHP :cool:

I have a main google webapp class, and a secondary class, which handles all the XML getting. One function within this XML class has a callback which fires when the XML is received from the server.
I would like all this call-backing to be handled within the XML class, and for a function to be triggered within the main class when it's all done, so it can update the web GUI.
The XML get is async, so I can't feed the XML as a function result, and OO structure prevents the secondary class calling a function in primary. (right?)

In the world of windows GUI, the window would handle the event easily, but in this wilderness, I'm left stuck for ideas. Am I missing something blindingly obvious here?

I'm not sure I fully understand what you are trying to accomplish, but here is an example as to how to update a UI component after the server sends the answer back:

code:
 public class MainClass implements EntryPoint
{
   private TextBox textbox; //our UI component

   public void onModuleLoad()
   {
     //initialize the textBox and add it to the main panel
     .....
     //call the server
     MyServiceAsync service=(MyServiceAsync)GWT.create(MyService.class);
     service.getTextBoxData(new AsyncCallback<String>(){
           public void onFailure(Throwable ex){
             textbox.setText("Failed");
           }
           public void onSuccess(String result){
             textBox.setText(result);
           }
     });
   }
}
This code assumes you have defined the MyService service interface that has a method "public String getTextBoxData();"

As you can see, from an inner class you can access private members of the enclosing class.

If you want to have a completely separate class that handles the server communication, its possible to do it too. The MainClass would just have to expose a method "public void setTextBoxData(String text)" that would be called by the server communication class (that class would obviously need a pointer to the MainClass).

Does this help?

Fruit Smoothies
Mar 28, 2004

The bat with a ZING

rhag posted:

Does this help?

Unfortunately not. My issue was communicating between classes. I eventually found that an interface based on EventListener was the way forward.

This annoyingly comment-less code tried to give me an understanding. I eventually implemented it, almost verbatim, but I really don't see the need to have an array of listeners. Surely, just the one would do?

Thanks for your explanation and time. I apologise for my hideous explanation.

EDIT: And that is the worst way of doing a loop I have ever seen.

Fruit Smoothies fucked around with this message at 16:49 on Jun 16, 2009

Volguus
Mar 3, 2009

Fruit Smoothies posted:

Unfortunately not. My issue was communicating between classes. I eventually found that an interface based on EventListener was the way forward.

This annoyingly comment-less code tried to give me an understanding. I eventually implemented it, almost verbatim, but I really don't see the need to have an array of listeners. Surely, just the one would do?

Thanks for your explanation and time. I apologise for my hideous explanation.

EDIT: And that is the worst way of doing a loop I have ever seen.

Yes, one listener would do, in your case.
But the code in there was providing a mechanism to have multiple listeners that can register themselves to be notified when an event occurs.
If you are 100% sure that you will never need more than 1 listener, you can take out the array, and instead have just a variable "private SignInListener listener" with a set and get.

Otherwise, you can leave the list of listeners in there, it won't hurt.

Fruit Smoothies
Mar 28, 2004

The bat with a ZING

rhag posted:

Yes, one listener would do, in your case.
But the code in there was providing a mechanism to have multiple listeners that can register themselves to be notified when an event occurs.
If you are 100% sure that you will never need more than 1 listener, you can take out the array, and instead have just a variable "private SignInListener listener" with a set and get.

Otherwise, you can leave the list of listeners in there, it won't hurt.

I don't see anywhere where the listeners are created... Making things in Java is one of the biggest confusions to me. It sounds silly, but I forget if i'm in a function, and don't need the "public" nonsense, or not. Then there's the weird syntax of "class classInstanceVar = ..." and not "name = class" as in other languages.

Where it's currently

code:
public void onSignInAttempt(boolean passwordOK)
    {
        for(Iterator it = listeners.iterator(); it.hasNext();)
        {
            SignInListener listener = (SignInListener) it.next();
            listener.onSignInAttempt(passwordOK);
        }
    }
does that get changed to
code:
public SignInListener listener; // "Global" variable

public void listenerSetter(SignInListener FromMainClass) {
  // Sets "global" var
  listener = (SignInListener)FromMainClass;
}

public void onSignInAttempt(...) {
   // call func in main class.
   listener.onSignInAttemt(...);
}
It just seems a little empty to be correct.

placid
Jul 11, 2006

Fruit Smoothies posted:

I don't see anywhere where the listeners are created...

Based on your description earlier, your main class is your listener.

code:
public MainClass
implements SignInListener
{
    public static void main(String[] args)
    {
        SecondaryXMLClass sXMLC = new SecondaryXMLClass();
        sXMLC.addSignInListener(this);
    }

    public void onSignInAttempt(boolean passwordOK)
    {
        
    }
}
Does that help clarify it?

placid fucked around with this message at 21:13 on Jun 16, 2009

Fruit Smoothies
Mar 28, 2004

The bat with a ZING

placid posted:

Based on your description earlier, your main class is your listener.

code:
public MainClass
implements SignInListener
{
    public static void main(String[] args)
    {
        SecondaryXMLClass sXMLC = new SecondaryXMLClass();
        sXMLC.addSignInListener(this);
    }

    public void onSignInAttempt(boolean passwordOK)
    {
        
    }
}
Does that help clarify it?

Yeah, I get that bit. I know how the XML class is created, I didn't know, since SignInListener doesn't appear to be a class, whether or not it needed a constructor. If it does, I couldn't see one.

Volguus
Mar 3, 2009

Fruit Smoothies posted:

Yeah, I get that bit. I know how the XML class is created, I didn't know, since SignInListener doesn't appear to be a class, whether or not it needed a constructor. If it does, I couldn't see one.

The SignInListener is not a class. Is an interface. Explanation here: http://java.sun.com/docs/books/tutorial/java/concepts/interface.html

What you'll have to do is basically provide an implementation of that interface (can be the MainClass or an anonymous one) to the SecondaryXMLClass.

placid showed you the situation when the MainClass is the SignInListener implementation. Here is the anonymous class method. Such as:
code:
SecondaryXMLClass sXMLC = new SecondaryXMLClass();
sXMLC.addSignInListener(new SignInListener(){
 public void onSignInAttempt(boolean passwordOK)
    {
        //do whatever you want in here. 
    }

});
But, before I would go any further and cause myself a lot of grief, I would pick up a book to read (or at least read the entire tutorial that I provided the link to).

Fruit Smoothies
Mar 28, 2004

The bat with a ZING

rhag posted:

The SignInListener is not a class. Is an interface. Explanation here: http://java.sun.com/docs/books/tutorial/java/concepts/interface.html

What you'll have to do is basically provide an implementation of that interface (can be the MainClass or an anonymous one) to the SecondaryXMLClass.

placid showed you the situation when the MainClass is the SignInListener implementation. Here is the anonymous class method. Such as:
code:
SecondaryXMLClass sXMLC = new SecondaryXMLClass();
sXMLC.addSignInListener(new SignInListener(){
 public void onSignInAttempt(boolean passwordOK)
    {
        //do whatever you want in here. 
    }

});
But, before I would go any further and cause myself a lot of grief, I would pick up a book to read (or at least read the entire tutorial that I provided the link to).

Yeah I've been looking around for Java information. The trouble is, I had no idea about this interfacing, since Delphi (:cool:) uses a windows-message-based event system IIRC. The lack of the "interface" keyword made it difficult to find things out.

Your help is very much appreciated.

teen bear
Feb 19, 2006

I finished my first year of CS about a month ago (only Java, up to Linked Lists, Objects, etc). Are there any reccommended books, tutorials, websites, or particular subjects that I should look in to? I'd like to keep working at it during the summer.

Shavnir
Apr 5, 2005

A MAN'S DREAM CAN NEVER DIE

Capc posted:

I finished my first year of CS about a month ago (only Java, up to Linked Lists, Objects, etc). Are there any reccommended books, tutorials, websites, or particular subjects that I should look in to? I'd like to keep working at it during the summer.

Is there a particular project you want to work on or an idea you want to follow?

HFX
Nov 29, 2004

Capc posted:

I finished my first year of CS about a month ago (only Java, up to Linked Lists, Objects, etc). Are there any reccommended books, tutorials, websites, or particular subjects that I should look in to? I'd like to keep working at it during the summer.

Where do you want to go? I can recommend Wrox published books as a great place to learn. They seem to mix good software engineering and have good explanations. However, if you want to learn about a particular item of interest in programming, I can taylor a better recommendation to you.

sonic bed head
Dec 18, 2003

this is naturual, baby!
In an effort to accomplish what I was trying to do on the previous page, I have decided to allow there to be a huge amount of JSP's. I'm up to about 20 at the moment and it's growing by the week. Oh well though, I'll make other people maintain them.

New problem though...I am using struts nested tags to either populate the forms for editing or print the forms for originally submission. Does anyone have any experience with these? I am using an ActionForm with ArrayLists that are being nested and I keep getting either null pointers or indexoutofbounds in the struts code and not in mine. Is there some format to these nested java beans that I'm not understanding?

teen bear
Feb 19, 2006

I'm not sure exactly where I'd like to go from here. So far I've just enjoyed figuring out whatever terrible assignment they had us do for class, so I thought I'd keep going on my own this summer.

What's the next logical step? What are some subjects that might be helpful or fun to learn?

1337JiveTurkey
Feb 17, 2005

Here's a few possible things to look at in the base API:

  • The java.io, java.util.zip, java.net and related basic IO libraries are very generally applicable.
  • RMI builds on the basic IO libraries to provide an easy way to write code distributed across many computers.
  • The java.text and java.regex text processing libraries can drastically simplify many things you've used lots of if-then statements for.
  • The Swing UI libraries are very powerful and a considerable upgrade from the command line.
  • JDBC is the standard way to connect to databases. You'd need a database for this, but there are many good ones out there.

I'd suggest avoiding anything related to Java Enterprise Edition, EJB or the like until you're thoroughly acquainted with the basics. There's also a huge number of open source projects to look through. Robocode in particular is a good choice for beginner programmers.

hey mom its 420
May 12, 2007

Capc posted:

What's the next logical step? What are some subjects that might be helpful or fun to learn?
Try a different language or two. Not a jab against Java, it's just good to know several languages, especially if they differ in paradigms. I'd suggest picking up Python, for instance.

Otherwise, I'd suggest solving Project Euler problems or just learning about data structures like balanced binary trees, B-trees, tries, hash maps, implementing these is loads of fun.

EDIT: Gah, I thought this was the general programming thread. The original point still applies though.

hey mom its 420 fucked around with this message at 13:27 on Jun 19, 2009

Kaltag
Jul 29, 2003

WHAT HOMIE? I know dis ain't be all of it. How much of dat sweet crude you be holdin' out on me?
I am writing an FTP client. I am testing downloading a jpg. When I download it, it looks all hosed up and when I examine it in a hex editor it seems only every 100th byte or so is messed up. Other than that the file is the correct size, the bytes seem to be in the correct order etc, its just that every 100th bit or so is messed up.

my download routine, it looks hosed up because I'm still working on it and has some other things I tried commented out

code:
public BufferedReader defaultIn = null; //binded to socket elsewhere
public BufferedReader passiveIn = null; //binded to socket elsewhere

public boolean download(String file)
{
        ArrayList<FTPFile> files = list();
        if(files.size() != 0)
	{
	        int i;
		for(i = 0; i < files.size(); i++)
		{
			if(files.get(i).getName().trim().compareToIgnoreCase(file.trim()) == 0)
			{
				System.out.println("File Size: " + files.get(i).getSize());
				break;
			}
		}
		send("TYPE I");
		System.out.println(getResponse(defaultIn));
		send("PASV");
		String portCommand = getResponse(defaultIn);
		System.out.println(portCommand);
		if(getPassiveSock(portCommand))
		{
			send("RETR " + file);
			System.out.println(getResponse(defaultIn));
	
			File f = new File(path + sensorName + "_" + file);
				
			byte[] fileBytes = new byte[Integer.parseInt(files.get(i).getSize())];
			System.out.println("filesize: " + files.get(i).getSize());
			try
			{
				FileOutputStream out = new FileOutputStream(f);
				//IMPORTANT PART GOONS!
				//while(passiveIn.ready())
				for(int j = 0; j < Integer.parseInt(files.get(i).getSize()); j ++ )
				{
					out.write(passiveIn.read());
					//fileBytes[j] = (byte) passiveIn.read();
				} 
				//out.write(fileBytes, 0, fileBytes.length - 1);
				out.close();
				System.out.println("Done Transferring File");		
			}
			catch (Exception e)
			{
				System.out.println("Problem Writing File");
			}
			closePassiveSock();
			return true;
		} 
		else 
		{
			closePassiveSock();
			return false;
		}
	}
	System.out.println("List command failed");
	return false;
}
This is the important part. Things commented out are other things I've been trying but end with the same problem.

code:
//byte[] fileBytes = new byte[Integer.parseInt(files.get(i).getSize())];
//while(passiveIn.ready())
for(int j = 0; j < Integer.parseInt(files.get(i).getSize()); j ++ )
{
	out.write(passiveIn.read());
	//fileBytes[j] = (byte) passiveIn.read();
} 
//out.write(fileBytes, 0, fileBytes.length - 1);
out.close
I think the issue lies in the read/write routine and somehow my data is being corrupted. BufferedReader.read() is the closest thing to reading a single byte I have and I haven't found any good alternatives.

I will add that this seems to work for text files and small files.

EDIT: I think the problem lies in that bufferedreader can not read a single byte, it reads ints instead. Even though I have not implemented the solution I will leave this up as I work so you can mock my code.

EDIT2: I am an idiot and need to use DataInputStream instead of bufferedreader

EDIT3: It worked

Kaltag fucked around with this message at 14:57 on Jun 19, 2009

Volguus
Mar 3, 2009

Kaltag posted:


code:
public BufferedReader defaultIn = null; //binded to socket elsewhere
public BufferedReader passiveIn = null; //binded to socket elsewhere

				FileOutputStream out = new FileOutputStream(f);
				//IMPORTANT PART GOONS!
				//while(passiveIn.ready())
				for(int j = 0; j < Integer.parseInt(files.get(i).getSize()); j ++ )
				{
					out.write(passiveIn.read());
					//fileBytes[j] = (byte) passiveIn.read();
				} 
				//out.write(fileBytes, 0, fileBytes.length - 1);
				out.close();
				System.out.println("Done Transferring File");		


But, but....why?
Why not go the basic way of reading from a stream and writing into another? A way that works for any stream?

code:

OutputStream out=(whatever you want, FileOutputStream if you please)
InputStream in = (from wherever you got it from. network, file, memory....)

byte[] data=new byte[1024]; //this is how much data we're reading at once
int read=0;
while( (read=in.read(data))>=0)
{
  out.write(data,0,read);
}
out.close();
in.close();
and...its faster. I don't even want to look at your CPU reading byte after byte......
For local file transfer a higher buffer means faster transfer (ideally the HDD is the bottleneck not the CPU). For network...its tricky since the speeds are not anywhere close to HDD speeds.
usually 1k is just about enough.

Volguus
Mar 3, 2009

Capc posted:

I'm not sure exactly where I'd like to go from here. So far I've just enjoyed figuring out whatever terrible assignment they had us do for class, so I thought I'd keep going on my own this summer.

What's the next logical step? What are some subjects that might be helpful or fun to learn?

Why not take a look at Google Summer of Code ? I believe the registrations are closed, but you can look at all the projects that applied, and get ideas from their projects. Maybe you can find something fun.

Personally, for 4 days now I've been writing a yum file system (fuse, not in kernel). I found it fun. Would it be fun for you? Dunno.

trex eaterofcadrs
Jun 17, 2005
My lack of understanding is only exceeded by my lack of concern.

rhag posted:

But, but....why?
Why not go the basic way of reading from a stream and writing into another? A way that works for any stream?

code:

OutputStream out=(whatever you want, FileOutputStream if you please)
InputStream in = (from wherever you got it from. network, file, memory....)

byte[] data=new byte[1024]; //this is how much data we're reading at once
int read=0;
while( (read=in.read(data))>=0)
{
  out.write(data,0,read);
}
out.close();
in.close();
and...its faster. I don't even want to look at your CPU reading byte after byte......
For local file transfer a higher buffer means faster transfer (ideally the HDD is the bottleneck not the CPU). For network...its tricky since the speeds are not anywhere close to HDD speeds.
usually 1k is just about enough.

Classes in the java.nio.channels package are even faster for reading/writing.

Volguus
Mar 3, 2009

TRex EaterofCars posted:

Classes in the java.nio.channels package are even faster for reading/writing.

That is correct. But we must learn to walk before we can run.

Patashu
Jan 7, 2009

rhag posted:

Why not take a look at Google Summer of Code ? I believe the registrations are closed, but you can look at all the projects that applied, and get ideas from their projects. Maybe you can find something fun.
Aww. :downsad:
It's closed, and it looks like something that would be just perfect for me to do. Anyone know of any alternatives?

Kaltag
Jul 29, 2003

WHAT HOMIE? I know dis ain't be all of it. How much of dat sweet crude you be holdin' out on me?
thanks for the side read/write tip

almostkorean
Jul 9, 2001
eeeeeeeee
Can someone help me understand how java passes in objects into functions? My previous understanding was that everything is passed by value and you can't pass by reference. But I'm working on this program where I'm using a union find data structure (it basically just holds a hashmap) and I'm doing something like this:

code:
UnionFind uf = new UnionFind();
im = connectComponents(width,height,uf);
im = drawImage(width,height,uf);
the uf that is passed into drawImage still holds all the information that was set in connectComponents. Can someone explain what's going on here?

Also, is there a good book or resource for how to make java code fast? I have a decent understanding of how to speed up code in c++ but not with java

OddObserver
Apr 3, 2009

almostkorean posted:

Can someone help me understand how java passes in objects into functions? My previous understanding was that everything is passed by value and you can't pass by reference.

That's correct, but what's being passed by value is a reference... To make it less confusing: below you say that you understand C++; well, saying Foo f = new Foo() in Java is about the same as saying Foo* f = new Foo() in C++. Similarly, every time you say SomeType st, you're declaring a variable that holds a pointer/reference to an object of that type.

lamentable dustman
Apr 13, 2007

🏆🏆🏆

almostkorean posted:

Can someone help me understand how java passes in objects into functions? My previous understanding was that everything is passed by value and you can't pass by reference. But I'm working on this program where I'm using a union find data structure (it basically just holds a hashmap) and I'm doing something like this:

code:
UnionFind uf = new UnionFind();
im = connectComponents(width,height,uf);
im = drawImage(width,height,uf);
the uf that is passed into drawImage still holds all the information that was set in connectComponents. Can someone explain what's going on here?

Also, is there a good book or resource for how to make java code fast? I have a decent understanding of how to speed up code in c++ but not with java

simply put, objects are by reference and primitives are by by value

not exactly but close enough

HFX
Nov 29, 2004

almostkorean posted:

Can someone help me understand how java passes in objects into functions? My previous understanding was that everything is passed by value and you can't pass by reference. But I'm working on this program where I'm using a union find data structure (it basically just holds a hashmap) and I'm doing something like this:

code:
UnionFind uf = new UnionFind();
im = connectComponents(width,height,uf);
im = drawImage(width,height,uf);
the uf that is passed into drawImage still holds all the information that was set in connectComponents. Can someone explain what's going on here?

Also, is there a good book or resource for how to make java code fast? I have a decent understanding of how to speed up code in c++ but not with java

Any object in java, including array is passed by reference.
Any primitive in java, is pass by value.
The passing of uf into connectComponents is copying the reference to the object, and so when it dereference that copy, it gets the original object. This is exactly like C++'s reference operator.


For your second question: http://www.cs.cmu.edu/~jch/java/speed.html covers many of the basics. However, before you start trying to write fast code:

Are you sure your java code is not fast now? Do you need to make it faster? Do you know where your slowdown is. Is your algorithm optimal for the data sets it will be run on. Is it optimal for the hardware it will be run on?

Max Facetime
Apr 18, 2009

almostkorean posted:

code:
im = connectComponents(width,height,uf);
When the Java Virtual Machine is executing that code, there are two data structures in play:

The one called the operand stack holds temporary values. These are pushed on top of the stack by copying a value from somewhere and removed from the stack by popping a value, giving it to something else.

The other one called a stack frame holds values that were used to invoke the current method and the values of any local variables. This is a 0-based array.

In the simple case, where your code resides in a class method and width, height and im are arguments, the method call goes like this:
  1. the value in stack frame[0] holding the value of width is pushed on operand stack.
  2. the value in stack frame[1], aka height is pushed on operand stack.
  3. the reference value in stack frame[2], aka uf is pushed as well.
  4. the method connectComponents is invoked by getting a new stack frame, popping the three values from the operand stack and storing them in new the new stack frame in positions 2, 1, 0 respectively, executing the method and finally pushing the return value to the operand stack.
  5. then, the reference value on the operand stack is popped and stored in stack frame[2], aka im.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

HFX posted:

For your second question: http://www.cs.cmu.edu/~jch/java/speed.html covers many of the basics. However, before you start trying to write fast code:

I just want to note that this page is extremely out-of-date and that much of its advice is now wrong. For example, in many cases on modern JVMs, System.arraycopy is not faster than using a loop.

HFX
Nov 29, 2004

rjmccall posted:

I just want to note that this page is extremely out-of-date and that much of its advice is now wrong. For example, in many cases on modern JVMs, System.arraycopy is not faster than using a loop.

Probably is. I usually find people who try to make java faster or more efficient end up making it worse. Really the JVM has gotten quite good at what it does. I know it is hard for C++ people to give up some of those habits of trying to optimize everything, but really learn to trust in the compiler and runtime enviroment. This actually goes pretty well for C/C++ with more modern compilers.

HFX fucked around with this message at 01:15 on Jun 25, 2009

Johnrox
May 14, 2008
I'm pretty new to Linux and I currently have Eclipse installed. I'm trying to implement a part of speech tagger and I'm having a lot of trouble. I want to install a package from http://nlp.stanford.edu/software/tagger.shtml and just run some quick tests but I can't get the package to read with eclipse.

WalletBeef
Jun 11, 2005

HFX posted:

Probably is. I usually find people who try to make java faster or more efficient end up making it worse. Really the JVM has gotten quite good at what it does. I know it is hard for C++ people to give up some of those habits of trying to optimize everything, but really learn to trust in the compiler and runtime enviroment. This actually goes pretty well for C/C++ with more modern compilers.

It sounds to me like the people you know which are trying to make their java code faster (and failing) are bad programmers. The only thing anyone should trust is a profiling tool which gives you hard answers to the questions of "Why is this application using this much CPU time and ram etc."

Don't trust the compiler or JVM, trust your code profiler.

HFX
Nov 29, 2004

WalletBeef posted:

It sounds to me like the people you know which are trying to make their java code faster (and failing) are bad programmers. The only thing anyone should trust is a profiling tool which gives you hard answers to the questions of "Why is this application using this much CPU time and ram etc."

Don't trust the compiler or JVM, trust your code profiler.

Well there is that too. Most people are terrible programmers. They will spend hours optimizing something that is completely pointless or worse premature optimize. Many of them try to fix programs on a linear speed basis where as thinking about it abstractly and having a better algorithm would suit them a whole lot better.

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip
clock(3) is my profiler

Fehler
Dec 14, 2004

.
I'm writing a Java application right now where several clients (around 40) play a simple game together. I'm going to start work on the server-client communication now, but before I start writing horrible code, I thought I'd ask here:

I guess the simple straightforward approach would be to write a server thread with a while(true)-loop with socket.accept() and then start a new thread for every new connection. Those threads would then wait for messages from the clients somehow (input stream) and notify the server thread by calling a special method, which would then loop over all connected client threads and call a method in all client threads to write to the socket.

But is this really the way to do this? Would it even work? Or are there ways in Java which would make this simpler and easier to maintain?

Contra Duck
Nov 4, 2004

#1 DAD

Fehler posted:

I'm writing a Java application right now where several clients (around 40) play a simple game together. I'm going to start work on the server-client communication now, but before I start writing horrible code, I thought I'd ask here:

I guess the simple straightforward approach would be to write a server thread with a while(true)-loop with socket.accept() and then start a new thread for every new connection. Those threads would then wait for messages from the clients somehow (input stream) and notify the server thread by calling a special method, which would then loop over all connected client threads and call a method in all client threads to write to the socket.

But is this really the way to do this? Would it even work? Or are there ways in Java which would make this simpler and easier to maintain?

It's possible to do it that way for small numbers of clients; have a main server thread that listens for connections and makes handler threads for each one, and then have the client threads read data, process it, send the output to each of the other clients and go back to read some more, but it gets pretty clunky as the number of clients goes up (40 clients sounds like you're getting into this range) and you'll have to spend a fair bit of time to make sure you don't run into any synchronisation issues.

A nicer method is to use the java non-blocking io classes in java.nio. I won't write my own example because some fine people have done this already, but basically it lets you read from an unlimited number of sockets at the one time. Effectively the code asks which sockets have data ready to read on them, deals with them each in turn and then asks again. No need for multiple threads, no synchronisation issues and it scales far better than the original method.

Fehler
Dec 14, 2004

.
Thanks for the link, but I'm not sure if will really help me. The way I understand the method, instead of keeping the connections to the clients open all the time, I would make the clients poll the server regularly. Wouldn't that cause even more load, since every client would have to send a request to the server every few 100 ms?

Contra Duck
Nov 4, 2004

#1 DAD

Fehler posted:

Thanks for the link, but I'm not sure if will really help me. The way I understand the method, instead of keeping the connections to the clients open all the time, I would make the clients poll the server regularly. Wouldn't that cause even more load, since every client would have to send a request to the server every few 100 ms?


It'll look a little different to that example, it'll probably require two threads, but the general principle is the same. You'll have a Selector object and a thread that is listening for connections and adding SocketChannels to the Selector. Then you'll have a second thread that asks the Selector for any Channels that are ready to be read. The SelectionKey determines the operation you're looking for, in that example it's set to ACCEPT but if you use READ then it'll return all the channels ready to be read.

Adbot
ADBOT LOVES YOU

Fruit Smoothies
Mar 28, 2004

The bat with a ZING
While we're on the subject of sockets; I've always prefered async non-blocking. Can someone tell me why I should do sync blocking instead? Should I?

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply