Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

[Java] DistributedSystem


PeRV
 Share

Recommended Posts

**DistributedSystem**
___________________________________________________________________

A childishly-simple system for sending and reading primitives
___________________________________________________________________

I made a very easy-to-use Java class that allows its users to communicate primitives across a network.
Its as-is implementation is meant to work as a utility class and serve various purposes based on its innate flexibility (it's meant to be complete the way it is).
Feel free to use and abuse it. The code is yours. I want this to help Java developers get their feet in the door with respect to online software development.

Here is an example of how it could be used:
```
DistributedSystem server = new DistributedSystem(12345);

server.send(123, 'a', "bc", true);

...

DistributedSystem client = new DistributedSystem("69.420.619.42", 12345);

int oneTwoThree = client.readInt();
char characterA = client.readChar();
String stringBC = client.readString();
boolean boolTru = client.readBoolean();

```
Here is the GitHub page:

* [github.com/piiearvi/DistributedSystem](https://github.com/piiearvi/DistributedSystem)
Link to comment
Share on other sites

In the interest of learning, you should change the class to public, all of the constructors to public and all of the methods there to public. Should also change your formatting so methods aren't starting on the same line as the end-bracket for the method before it in the code.

That being said, despite your code style being… interesting... it is consistent, and consistency is good. Keep up the good work.
Link to comment
Share on other sites

@'pandacoder':

> […] you should change […]

I am familiar with Java coders and their obsession with the "public" keyword. When you stop using it as much and understand what kind of scope no access modifier gives you, not only does your code look less intimidating, but also:

@'Marsh':

> […] things are private for a reason.

The class is used throughout your project. No package importing necessary since it defaults to package-private (default package). There's a reason why Java's default access modifier is not public, but nobody ever stops to ask why. I'd say it's because libraries made using no access modifier are lighter-weight and more casual on a per-project basis. It's like when your professor assigns a project where you use her helper class. You don't import a JAR necessarily. The simplest way is to just drop in their helper class' class file. If it has a package namespace, then you're going to import it. If not, you just start slinging away. The informalities are easier but less "corporate."

@'pandacoder':

> […] change your formatting so methods aren't starting on the same line as the end-bracket for the method before it in the code.

I only do this for methods that are overloading each other. I could spread them out or put proper spacing in there, so I'll do that actually. They're still going to be back-to-back because it's part of this style guideline I follow, but I'll add more appropriate spacing because they'll be easier to read and plus it's also part of that same guideline.
Link to comment
Share on other sites

Also to add the fact that making code private that should be rather than making everything public adds extra protection for your program. The public everything idea is one reason why Java is red flagged as a huge security hole. It is also a reason why Google when making android wanted to private functions to prevent known security holes from occurring. My advice is to do what PeRV did Panda and learn how to use modifiers how they should be and the reasons behind them if your going to program in any Language.
Link to comment
Share on other sites

@'Genusis':

> […] The public everything idea is one reason why Java is red flagged as a huge security hole. […]

I agree with this because it is definitely a form of **security through obscurity**. It'll save your ass more times than not. That's also why people always say (even Java coders) **composition over inheritance**. Composition requires that you yourself re-implement which methods should be exposed or even what should be visible in the first place.
Link to comment
Share on other sites

that is also true as well marsh. Though a majority of the time most things can be private without breaking anything especially if you programmed it that way to begin with. I do however suggest to use private whenever possible. And also if your referring that to googles changes they made at one point. Those never broke anything. Oracle just through a fit because Google made certain functions private in the java libraries that was not being used directly, which did increase overall security of java on androids. Funny thing Oracle won the lawsuit and google was forced to change it back. Oracle never made those changes themselves. It is one of the few reasons i dislike Java and tend to not ever install it unless i have to to help someone or to play a game that uses java.
Link to comment
Share on other sites

@'Dialectics':

> These comments are cringe inducing.
>
> Why are you using the PrintWriter? Just pack the data directly into a byte array using simple bitwise and shift operators.

bitwise and shift operators only work on the bit level. This wont do you any good if you are trying to add data into a byte array. The closest thing you could do to get this to work in to use a memcpy function which can copy each byte into the array of data: https://gitlab.com/ascendingcreations/swift/blob/master/net/source/buffer_stream.c#L162
Link to comment
Share on other sites

@'Dialectics':

> These comments are cringe inducing. […]

Then post them on some Stack Overflow cringe compilation… lol

@'Dialectics':

> Why are you […]? Just […].

I chose PrintWriter because it works as a nice sister class to BufferedReader. They both handle streams like line-by-line high level I/O. I guess I could push things in chunks as byte arrays, but the classes do that for me. Are you using this and noticing inefficiency? If so, then I'd also say that I should probably insert my own version of a lighter weight pseudo-TCP using UDP and efficient abstractions; otherwise, I feel like you're just pontificating. Please, show us some Java code that uses bit shifting and bitwise operations providing equally efficient abstraction at the level this class is. Yeah, it's possible, but **don't insult us by calling our comments "cringe."** On that defensive note, you're just being plain rude :D
Link to comment
Share on other sites

@'Genusis':

> bitwise and shift operators only work on the bit level. This wont do you any good if you are trying to add data into a byte array. The closest thing you could do to get this to work in to use a memcpy function which can copy each byte into the array of data: https://gitlab.com/ascendingcreations/swift/blob/master/net/source/buffer_stream.c#L162

I'm not even going to bother addressing you. Honestly, educate yourself before you say something quite so dense again.

Here's how you can convert a 32 bit integer into a byte array (big endian):

byte[] byteArray = new byte[4];
for (int i = 0; i < 4; i++) {
bytes _= (byte)(integerToConvert >>> (i * 8));
}

You could also simply use Java's ByteBuffer class._
Link to comment
Share on other sites

Yeah, see.. I.. just wow.. I guess if getting super low level and ultra-conservative does it for ya then by all means, but you all should be very aware that modern day CPU's and BUS speeds don't even notice a byte, or two, or three, or a million. The average person has an internet connection that is consistently over 5mb/s. A friggin' byte array and how it's arranged is the least of your worries; making something pretty and functional is. ^_^

Also, I'd love to see you expand on this. How about removing the need to pack and unpack each variable one by one (or by passing values as arguments), e.g. reflection? Is there a Java equivalent of Lidgren out there?
Link to comment
Share on other sites

@'Budweiser':

> […] e.g. reflection?  Is there a Java equivalent of Lidgren out there?

I thought about it. I'm deciding on whether or not I should use serialization because then people can read objects and cast them to their class name. I'm still thinking though.
Link to comment
Share on other sites

@'Dialectics':

> I'm not even going to bother addressing you. Honestly, educate yourself before you say something quite so dense again.
>
> Here's how you can convert a 32 bit integer into a byte array (big endian):
>
> byte[] byteArray = new byte[4];
> for (int i = 0; i < 4; i++) {
>    bytes _= (byte)(integerToConvert >>> (i * 8));
> }
>
> You could also simply use Java's ByteBuffer class.
>
> I admit I was wrong. I forgot that Java supported bit manipulation.
> anyways, its not worth doing this because the Java compiler automatically does this for you anyways.[Edit]
>
> Anyways the above code would be more efficient if you pre-created the buffer set a size to lets say a power of 2 and then checked that buffers size to what data is being added into it then resized to the next power of 2 and so on. its inefficient to resize or create a new array each and every time you need to add something into the array._
Link to comment
Share on other sites

@'Genusis':

> […] the above code would be more efficient if you pre-created the buffer […]

That's what any I/O stream class containing a flush method currently does. If you look into their fields (albeit "protected" access), you'll see one by the name of "buf" that is of _byte[][/i] type.

But these things were already taken into account when base class abstraction classes were designed for streams. The only inefficiency of my class is probably everything coming in assumes by default to be a UTF8 string when that may not be the case always.

Even so, nitpicking any of this is silly and a waste of time. I doubt anyone complaining about the implementation even cares to use this anyways (let alone even bother benchmarking some results).

I made this library for people to create, not to complain (lol).

Also:

@'Dialectics':

> Here's how you can convert a 32 bit integer into a byte array (big endian):
>
> byte[] byteArray = new byte[4];
> for (int i = 0; i < 4; i++) {
>    bytes _= (byte)(integerToConvert >>> (i * 8));
> }
>
> I don't know why you're being so picky with details when you didn't even bother to unroll an **n=4** for-loop. And don't even get me started on why you think we need cases for big endian and little endian; we're getting pretty tedious here. Also, why use multiplication for your **i*8** when you can just bitshift left by 3? All of this implementation counselling is a waste of our time. Micro optimizations will literally end you if you don't watch it–the mentality sucks the life out of developers who could otherwise be **actually spending their time making something; correctness first; efficiency second.
>
> –-Edit------------------------------**
> On further thought, I am going to be changing this library to the name of "Pipo" and use an underlying ByteBuffer model to handle primitive data streaming. It'll still work with networking, but it will also work files and any other input and output accessible streams.__
Link to comment
Share on other sites

@'Marsh':

> There is nothing wrong with that coding style at all. It is actually fairly common.

I specifically did not use the word "wrong", only "interesting" and "consistent", and I have not seen it used in any well-supported open-source Java projects.

@'Marsh':

> There is nothing wrong with that coding style at all. It is actually fairly common.
>
> Also changing everything to public seems like a bad idea… Things are private for a reason.

I specifically said the class itself, the constructors and the methods, which from looking at the code I can see no good reason for any of them being package-private.

@'PeRV':

> @'pandacoder':
>
> > […] you should change […]
>
> I am familiar with Java coders and their obsession with the "public" keyword. When you stop using it as much and understand what kind of scope no access modifier gives you, not only does your code look less intimidating, but also:
>
> @'Marsh':
>
> > […] things are private for a reason.
>
> The class is used throughout your project. No package importing necessary since it defaults to package-private (default package). There's a reason why Java's default access modifier is not public, but nobody ever stops to ask why. I'd say it's because libraries made using no access modifier are lighter-weight and more casual on a per-project basis. It's like when your professor assigns a project where you use her helper class. You don't import a JAR necessarily. The simplest way is to just drop in their helper class' class file. If it has a package namespace, then you're going to import it. If not, you just start slinging away. The informalities are easier but less "corporate."
>
> @'pandacoder':
>
> > […] change your formatting so methods aren't starting on the same line as the end-bracket for the method before it in the code.
>
> I only do this for methods that are overloading each other. I could spread them out or put proper spacing in there, so I'll do that actually. They're still going to be back-to-back because it's part of this style guideline I follow, but I'll add more appropriate spacing because they'll be easier to read and plus it's also part of that same guideline.

- Having been programming in Java both educationally and a hobby for the last roughly 6 years, and professionally during the last 3 years for various different purposes, I am acutely aware as to what the access modifiers do in Java, and use package-private instead of public where it makes sense or makes an actual difference in the data.

- That class is not being used throughout your project unless your entire project is in a single package, and that would be poor design.

- Unless added to a package the class cannot be used outside the default package, which goes back to the single package idea (poor design, except this time it's somewhat worse since its the default package).

- I noticed that it was for only overloading methods (although by definition those read methods are not overloaded, so technically you did this for overloaded concepts), so I didn't say it was wrong, just interesting as I have never seen that done before, and at least for me makes it a little bit more difficult to read (I'm not advocating for copious amounts of whitespace, but putting the methods even on the next line rather than the same like as the closing bracket makes it more readable, but to be honest if the class works flawlessly there's really no reason for anyone to ever need to read it, but this puts slightly more pressure on you and makes documentation not possible in a neat manner).

- Making specific things private, protected or package-private in the interest of security and only making what is needed to be public public is good practice. That being said, this class is a utility class, and unless the fields were made public I do not see a security issue resulting that stems from the code rather than the JVM itself.

- I can think of many reasons as to why one might need to access this class from outside of the package, for example sub-classes of an abstract I/O class that were moved into a sub-package (sub-packages are treated as entirely separate packages and are excluded from package-private) in a neatly laid-out project. Another more important reason is so that dependencies are obviously separate from other code, which helps to avoid naming collisions as well as maintain clarity as to what came from what. This point I could actually concede, however, if the class was actually documented to make it obvious that it is not part of the project it was included in.

- Ultimately if you only want this to be usable within a single package, then really there is no reason to adhere to any library code standards, and you can disregard everything else I said (although I do recommend adding documentation even if you don't want to change visibility, and in the class's documentation you should specifically mention your rationale for the package-private visibility).

@'Genusis':

> Also to add the fact that making code private that should be rather than making everything public adds extra protection for your program. The public everything idea is one reason why Java is red flagged as a huge security hole. It is also a reason why Google when making android wanted to private functions to prevent known security holes from occurring.  My advice is to do what PeRV did Panda and learn how to use modifiers how they should be and the reasons behind them if your going to program in any Language.

@Genusis: While I am by no means an expert in any language, access modifiers are one of the points I put more emphasis on than almost everything else, specifically because when I write code that is meant to be used by others I have absolutely no faith that the other programmer will not do something they were not intended to do, so I use things like private and package-private liberally, where-as I use things like protected and public rather sparingly. Public, more than any other modifier, is meant for things that are immutable, or meant to be mutable without posing any inherent risk. Changing what I said to be public in this class would not pose any risks.
Link to comment
Share on other sites

  • 1 year later...
Err, I don't know if anyone cares about this thread anymore or anything but DataInputStream and DataOutputStream handle primitives really nicely so just feed them into bufffered input / output streams on TCP sockets and you are done. Then all you need to do is be careful what you send things as, you might be working with ints for example but if it's never going to be over 127 then write / read it as a byte etc.

Read the source code for those streams and you will see they convert the primitives to bytes for you, there is no need to "optimise" or manually complicate things beyond that point. The next level of efficiency you would want to look into is batching packets together wherever possible so you are only flushing a minimum number of times, this is because if you are using the datastreams correctly you will be sending a lot of small packets that are individually under the minimum TCP packet size so the majority of stuff you send (this dude stepped left, this dude hit that dude, etc…) will actually be padded anyway!

I'm not going to comment on "make everything public" gate, smh.

Liam
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...