Networking with ObjectInputStream, Java and Lua clients across TCP sockets - java

I have a Java server that will have two difference types of clients, a Java based console, and a Lua based client that the server will be controlling. I have got the Lua client to talk back and forth with
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
I am now trying to get a Java based client to connect and I would like to use
out = new ObjectOutputStream(new BufferedOutputStream(socket.getOutputStream()));
in = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
The problem I am having is understanding the best way to go about accepting connections, not knowing if it is a Lua or Java client on the other end. Then setting up the proper streams.
Should I just use different ports on the initial connection? I was hoping something more along the lines of sending a string from ObjectOutputStream that BufferedReader could read. Or should I use something lower level to see what is connecting before setting up if it is PrintWriter or ObjectOutputStream.
A link to an in depth tutorial or actual code would work. I am having trouble finding resources beyond the basic setup of one or the other.
Thanks in advanced.

Inasmuch as you propose to provide what sounds like two completely different services, it would be natural and appropriate to provide them at different ports. To implement that, your server would create and manage two separate ServerSockets, listening on different ports. One would provide one service; the other would provide the other. You could use either threads or a Selector or a combination of those to handle the two server sockets and all the clients.
As a separate matter, I urge you to think carefully before relying on Object streams. If you can implement your service on top of a simpler and/or more general protocol then you will avoid the multiple joys of Java Serialization, and you will also leave open the door for clients written in other languages.

Related

sending serialization file via sockets in java

System.out.println("Java is awesome!");
Pardon my enthusiasm; I just can't believe how powerful Java is, what with its ability to not only save objects (and load them), but also with its main purpose, to send them over a network. This is exactly what I must do, for I am conducting a beta-test. In this beta-test, I have given the testers a version of the game that saves the data as Objects in a location most people don't know about (we are the enlightened ones hahaha). This would work fine and dandy, except that it isn't meant for long-term persistence. But, I could collect their record.ser and counter.bin files (the latter tells me how many Objects are in record.ser) via some client/server interaction with sockets (which I know nothing about, until I started reading about it, but I still feel clueless). Most of the examples I have seen online (this one for example: http://uisurumadushanka89.blogspot.com/2010/08/send-file-via-sockets-in-java.html ) were sending the File as a stream of bytes, namely some ObjectOutputStream and ObjectInputStream. This is exactly what my current version of the game is using to save/load GameData.
Sorry for this long-winded intro, but do you know what I would have to do (steps-wise, so I can UNDERSTAND) to actually send the whole file. Would I have to reconstruct the file byte-by-byte (or Object-by-Object)?
Its pretty simple, actually. Just make your objects serializable, and create an ObjectOutputStream and ObjectInputStream that are connected to whatever underlying stream you have, say FileInputStream, etc. Then just write() whatever object you want to the stream and read it on the other side.
Heres an example for you.
For sockets it will be something like
ObjectOutputStream objectOut = new ObjectOutputStream(serverSocket.getOutputStream());
ObjectInputStream objectIn = new ObjectInputStream(clientSocket.getInputStream());
Java Serialization is an immensely powerful protocol. java.io.ObjectOutputStream and java.io.ObjectInputStream are the higher level classes which of course are wrapped with the lower level classes such as FileInputStream and FileOutputStream. My question is why do you wish to read the file byte by byte when the entire file can be read in Objects.
Here is a good explanation of the procedure.
http://www.tutorialspoint.com/java/java_serialization.html

Java: How to monitor a plain socket connection (and forward results to the internal logger)

I am spoiled by Netty but now comes day of reckoning...
I got a plain java.net.Socket here (to be more specific, a custom SocketPoolFactory where Sockets are created along with a corresponding OutputStreamWriter and InputStreamWriter which wrap the socket's IO-Streams) and I need to monitor what is sent and received (in order to write this to the log file for debugging purposes).
Seems like I have a tough time to figure out where to hook in and intercept what is sent/received.
Can somebody help? What's the best to do this?
It is only for debugging (so does not need to be top notch efficient) (and if it helps somehow: I am working with Groovy).
Write your own FilterInputStream-derived class and interpose it in the stream stack attached to the socket,

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? :)

how to read mails from gmail with imap by using java socket

I'm kinda interested in with java sockets in these days and i want to read my mails from gmail with using java socket. is it possible?
Socket s;
s = new Socket("imap.gmail.com", 993);
InputStream in;
in = s.getInputStream();
BufferedReader sin = new BufferedReader(new InputStreamReader(in));
PrintWriter output = new PrintWriter(new OutputStreamWriter(s.getOutputStream()));
String line;
output.println("a001 LOGIN my-e-mail my-pass");
output.flush();
while ((line = sin.readLine()) != null)
System.out.println(line);
s.close();
what should i do after connecting to socket?
thanks in advance. (notice: i dont want to use java mail api, things get really easy with it, i'm just choosing this way to get familiar what's going on behind the scene)
edited the code.
If you feel like getting familiar with IMAP at GMail, you're going to have to put SSL/TLS on top of it. All GMail traffic is encrypted.
Once you have a socket you implement the IMAP protocol on it.
https://www.rfc-editor.org/rfc/rfc3501
+1 for the question.
EDIT: Yes, it is possible to speak to IMAP server using java sockets and in some cases it might be advisable to do so rather than using java mail library.
Using javamail is the easy way out. It is also appears to be the obvious solution but, there are cases when you do not want to go that route.
Javamail is highly unsuiatble for scaled out deployments with a large number of concurrent users that need to be kept notified on near real time basis.
Say, you want to service more than 1000 users per jvm and want to keep the overhead of creating imap connections low then, you will resort to implementing sockets yourself and write IMAP commands in the socket itself. Needless to say, other benefits include near instantaneous delivery of a new email to your user i.e if you are using AJAX.
Near instantaneous email is one of the few things left to like about Blackberry. Given RIMs scale, I don't think they would be using Javamail on top of IMAP to push out emails. That would be highly non-performant.

How can I send data in binary form over a Java socket?

I've seen lots of examples of sending serialized data over sockets in Java, but all I want is to send some simple integers and a string. And, the problem is I'm trying to communicate these to a binary written in C.
So, bottom line: how can I just send some bytes over a socket in Java?
You can use the simple OutputStream given by the Socket.
From there you can write bytes.
If you want you can also encapsulate this stream in a BufferedOutputStream to have a buffer.
I would really recommend not using the Java Sockets library directly. I've found Netty (from JBoss) to be really easy to implement and really powerful. The Netty ChannelBuffer class comes with a whole host of options for writing different data types and of course to can write your own encoders and decoders to write POJOs down the stream if you wish.
This page is a really good starter - I was able to make a fairly sophisticated client/server with custom encoders and decoders in under 30 minutes reading this: http://docs.jboss.org/netty/3.2/guide/html/start.html.
If you really want to use Java sockets. The socket output stream can be wrapped in a DataOutputStream which allows you to write many different data types as well, for example:
new DataOutputStream(socket.getOutputStream()).writeInt(5);
I hope that's useful.
I would recommend looking into Protocol Buffers for the serialization and ZeroMQ for the data transfer.

Categories

Resources