Java networking, beyond a simple chatroom - java

So I recently followed this tutorial on making a basic chatroom in Java. It uses multithreading and is a "connection-oriented" server. I was wondering how I could use the same Sockets and ServerSockets to send, say, the 3d position of an object instead of just a string?
Currently, the basic chatroom system just sends a string to the server and then the server sends it to all connected clients. What I want is to be able to have a client change the position of an object (most likely their character), and send the change of position to the server. Then (I would imagine) the server would send that change in position to each of the clients connected to it, and each client would in turn render this object at its new position.
I was wondering what the best way to do something like this was?
Would it be to send a string and have the server parse it into a coordinate?
Can I write more than one thing to a DataOutputStream at once?
I feel like I may have explained this poorly, so please ask some clarifying questions.
Thanks!

Create a Domain Object Model for your coordinate system. Then represent the changes to the positions using the objects in the above model. Serialize them into a transportable string like XML, JSON etc. Then unmarshall/deserialize the String to the original object and act upon them.
This separates your transport layer (using sockets to bradcast stuff) from the actual business logic (placement of objects) and the system becomes extendible.

Related

How to send packets continuously through TCP?

I have one server and multiple clients. The server is sending byte arrays(which includes some kind of messages inside) to the client and client parses those arrays into understandable forms.
Another point is, there is one special kind of message that the server send which client has to respond to it.
I want the server send regular messages continuously without expecting a response, and also special kind of message which expects a response and if it doesn't get it, it will terminate the connection.
How could I do that? I have been checking the net but could not find anything.
Server--->Client(Door Opened)
Server--->Client(Door Closed)
Server--->Client(Are You There?)
Client--->Server(Yeap)
Server--->Client(Plane Has Landed.)
Server--->Client(Are you There?)
.
.
.
Your question is pretty broad, so the answer is broad, too.
Remember about segregation of concerns respectively single responsibility principle. Coming from there: you are actually looking at two different functionalities here:
the regular data transfer from the server to known, connected clients (where no response is expected)
some form of "hearbeat detection" - where the server asks the client to check if they are still reachable/alive
When you think about that, it becomes clear that you probably want to use completely different "components" within client and server to provide these two different functionalities. Like in: even having two different ports (and even different threads) within client/server.
So the server keeps a list of known clients. One thread is sending data to the clients; another thread is periodically iterating that list and asking for heart beat answers. If no answer is coming in time, that client gets removed from the list.

Send a Data Record through TCP in java

I'm a Delphi developer and recently I decided to port one of my programs to java and I'm doing the server side program in java to make it cross-platform.
In Delphi, I could easily send a record as an array of bytes through TCP but I don't have much experience in java and I have no idea how to do it in an easy but moderated way.
Here is a sample of my data record:
type
Tlogin = record
username : string[50];
password : string[50];
version : word;
end;
And I would just simply send this type of record after making it an array of bytes.
Any ideas how to make such data records in java and how do I set size for strings, or any better suggestions to handle strings for sending them through TCP.
In Java, you simply send objects over the sockets between a client and server and there are a number of ways to do that. For a related reference please visit
Sending objects over Java sockets
For a more step by step example visit the following link:
JGuru - Sending objects over a socket
In your case your object would look as follows
class TLogin implements Serializable
{
private String userName;
private String password;
private int version;
//implement your objects methods below
}
Fields within the object that you do not want to participate in serialization and de-serialization can be marked as transient
For a detailed step by step example of serialization visit
Java Serialization Example
Edit based on the comment provided to my earlier response.
Serialization in simple words : It is a technique where-in a Java object is converted to a byte sequence (essentially, all fields of the object except those marked transient are a part of this byte sequence). This byte sequence can then be used to re-construct the object at a later point of time. The byte sequence obtained by serializing an object can be either persisted to a store or transmitted over a network channel, in order to have it re-construct the object at a later stage.
Serialization is at the core of a lot of communication protocols that happen within a client server environment within Java using either of RMI, Sockets or SOAP.
Having talked about serialization , we come to the client-server problem.
In case, the plan is only to port the server side code to Java then you have the following options to enable communication between the client and server:
Design the server to use SOAP/REST to communicate with the Delphi client.
Augment your record with a header data structure that contains information about the length and type of the data being stored and use this header within the client transmitted byte sequence on the server side to re-construct the object.
However, in my opinion the first method is better than the second since
it is a standard inter-operable technique.If at a later point of time you wish to port the client to some other language like C# or Python, you do not need to change the server.
it lets the web service infrastructure handle the nitty gritty of
SOAP/REST serialization and lets you focus on the business logic
I hope this lengthy answer points you in a direction towards the solution

Java Chat system protocol design, how to determine message type?

I have a chat program implemented in Java. The client can send lots of different types of information to the server (i.e, Joins the server and sends username, password; requests a private chat with another user on the server, disconnects from the server, etc).
I'm looking for the correct way to have the server/client differentiate between 'text' messages that are just meant to be chat text messages sent from one client to the others, and 'command' messages (disconnect, request private chat, request file transfer, etc) that are meant for the server or the client.
I see two options:
Use serialized objects, and determine what they are on the receiving end by doing an 'instanceof'
Send the data as a byte array, reserving the first N bytes of the array to specify the 'type' of the incoming data.
What is the 'correct' way to do this? How to real protocols (oscar, irc) handle this situation?
I've googled around on this topic and only found examples/discussions centering on simple java chat applications. None that go into detail about protocol design (which I ultimately intend to practice).
Thanks to any help...
Second approach is much better, because serialization is a complex mechanism, that can be easily used in a wrong way (for example you may bind yourself to internal content of a concrete serialized class). Plus your protocol will be bound to JVM mechanism.
Using some "protocol header" for message differentiation is a common way in network protocols (FTP, HTTP, etc). It is even better when it is in a text form (people will be able to read it).
You typically have a little message header identifying the type of content in all messages, including standard text/chat messages.
Either of your two suggestions are fine. (In your second approach, you probably want to reserve some bytes for the length of the array as well.)

Network Communication TCP [Code Design]

I've been messing a lot with TCP/IP Communication the last few days (Using Java and C#). I understand how it works and am able to use it. My Question is more a code design question, how its done the best and easy way to make a real communication.
For Example ive Built my own Multiuser Chat Server. I want my Communication to be able to decide wather its an Auth request, or a new chat message the ability to get the current user list etc etc.
Ive implemented a few ways on my own, but im not quite happy About that since i think theres a more standard and beauty way to do this.
My first thought was a String with Delimiters wich gets splitted, here is the Example of my Implementation of my Communication in Java:
//The Object-types im Using
clientSocket = new Socket(host, port_number);
_toServer = new PrintStream(clientSocket.getOutputStream());
_fromServer = new DataInputStream(clientSocket.getInputStream());
//Example Commands my Client sends to the server
_toServer.println("STATUS|"); //Gets the Status if server is online or closed (closed can occur when server runs but chat is disabled)
_toServer.println("AUTH|user|pw"); //Sends an auth Request to Server with username and Password
_toServer.println("MESSAGE|Hello World|ALL"); //Sends hello World in the Normal Chat to all Users
_toServer.println("MESSAGE|Hello World|PRIVATE|foo"); //Sends hello World only to the user "foo"
_toServer.println("USERS|GET"); //Request a list of all Connected Users
//Example In the Recieved Message Method where all The Server Messages Get Analyzed
serverMessage = _fromServer.readLine(); //Reads the Server Messages
String action = serverMessage.split("|")[0];
if (action.equals("USERS")) { //Example "USERS|2|foo;bar"
String users[] = serverMessage.split("|")[2].split(";");
}
if (action.equals("MESSAGE")) { //Example "MESSAGE|Hello World|PRIVATE|foo"
if(serverMessage.split("|")[2].equals("ALL") {
//Code and else for private....
}
}
if (serverMessage.equals("STATUS|ONLINE")) {
// Code
// I leave out //Code and } for the next If statements
}
if (serverMessage.equals("STATUS|OFFLINE")) {
if (serverMessage.equals("AUTH|ACCEPTED")) {
if (serverMessage.equals("AUTH|REJECT")) {
Is this the way its normally Done? Ad You See I need to send Statuscodes and Objects Corresponding to the Code. Ive Thought about Writing the Data in Bytes aswell and Implementing a "Decoder for Each Object", Example:
int action = _fromServer.readInt();
//opcodes is just an Enum Holding the corresponding int
switch(action) {
case(opcodes.MESSAGE):
break;
case(opcodes.AUTH):
break;
}
Note that this is more over a general design Question not just for this Chat Server Example, I think im Implementing a little Network Based Console Game just for Practise.
Is there a better way to do this or even an API/Framework?
Thanks in advance!
Essentially you're designing a protocol. There are a number of communication protocols that can handle this, the main one that comes to mind is IRC. I'm sure you can do a web search for tips on how to implement the protocol.
As for extending something like this for a console game, well I would start with implementing IRC, and using that to learn how real communication protocols are written. Once you've done that you can build on it to add your own commands to your framework.
If you are designing a protocol for inter-language communication, I would suggest not to use formated Strings as a means of communication but statusbytes. If you consider for example the design of TCP/IP itself you will find, messages consist of a fixed-format header and a variable payload. That way you always know, that (e.g.) the third byte of the message contains the messagetype, the fifth denotes an errorstate and so on. This makes handling easier.
If you have designed your protocol, you could consider working with explicit MessageObjects on the java-side, in which case you would implement a factory with marshalling and unmarshalling methods for these objects, converting objects from and to messages in your protocol.
If you are all-java you can even spare that effort and use ObjectInputStreams and ObjectOutputStreams on client and Server. If you are not, you might want to take a look at the Google Protocol Buffers: http://code.google.com/intl/de-DE/apis/protocolbuffers/, which do essentially the same for inter-language communication.
If your project grows, you may want to have a look at Netty - it's a framework for dealing with communication code. If your code is simple, you will be better off doing things manually.
As for protocol design, it depends on what is most important for you: performance, extensibility, human-readability, ease of debugging etc. These criteria may oppose each other to some degree, for example high performance may mean preference for binary protocols, but these negatively impact ease of debugging and sometimes extensibility. It's usually a good idea to not reinvent the wheel. Get inspired by existing protocols. If you choose to go binary, don't start from scratch unless you really have to, start with Protocol Buffers. If your app is simple and not aimed at very high performance, use a human-readable protocol which will make your life easier (debugging and testing are possible with standard shell tools such as strace and nc).
I think Apache MINA will help you. http://mina.apache.org/
Building a Java C/S application is really complex, you need to deal TCP, UDP and multi threads programming; MINA can help you for these things.
I think the other part you need is your private chatting protocol, but how about the open sourced IM service like Jabber? :)

Java client and server problems

I've editted this post based on recommendation by a fellow user.
My specific problems are as so:
Currently when I run Server.java, it loads up a map with a player on it, you cannot move the player which is how I intended, it simple creates a new "runGame".
The idea is when I run Client.java, it enables the player to move around the map, by creating a new Craft object, as it is now, for some reason it creates another map with the player on it (two running now) and neither of which has movement.
I am not sure how to explain it further, what I would like to know is how would someone go about creating a server and client that opens a background, and adds an object that is moveable via keys but only when a client has connected to the server?
I hope this is worded better than my last attempt.
thank you.
Without looking at the technology specifics, I think stepping back and looking at the overall architecture would be constructive here.
What state needs to be shared ? From the above I guess it's the game board and the state of the two players. So I would put that in one server process. Now the client process (a different instance per player, but the same executable) just needs to connect, make a move, and receive new board information when the other player(s) move.
The server process contains the board, the state of play etc. The clients simply need to be able to reflect that by drawing the board as represented by the server, and handling player inputs. I think you need one server deployable, and one client deployable, with a separate instance per user.

Categories

Resources