I have an application where I have to send Signals and Data between two entities.
Which way is best practice and why?
Open 4 sockets, 2 for signals in both directions and 2 for data in both directions
Open 2 sockets each for data and signals
Just open 1 socket and filter for signals and data
First of all sockets are full-duplex, i.e. you don't need a separate socket (connection) for sending and receiving.
Secondly, it's hard to tell without going into more details. However knowing the history of HTTP (one connection for commands/headers and data) and FTP (separate connections for commands and data) seems like HTTP designers made a better choice. Two connections is more code to maintain, also some firewalls don't like hanging, idle FTP command connection when large portions of data are transferred.
So, go for one connection, it's easy to distinguish between signals and data (flag, header, etc.) Also incoming and outgoing channel is completely orthogonal.
Why can't you just have 1 socket for all data and 1 socket for all signals. You can send signals to the remote entity while reading signals from the remote entity from the same socket. This is sort of like how FTP (non-passive) works, you have a control connection and then one used for the actual data transfer.
Having 4 sockets seems overkill, but I don't know the context of what the signals or data are.
If you don't mind more code to decode the network communication, you can definitely do it all in one socket. It'll require more thought into the actual communication, a better "protocol" if you will. Both the 2 socket and 1 socket model are fine.
There is a possible "middle way" - use JBoss remoting or similar to multiplex several virtual sockets on top of one real one. That way you can keep the data and control channels separate at the application level but still require only one TCP port (and thus at most one firewall hole) at the operating system level.
Another way: use a dedicated middleware, built for realtime application like 0MQ.
To instantiate ØMQ:
Jzmq obj = new Jzmq (hostname);
Where hostname is name or IP address of the box where zmq_server is running.
To create wiring, createExchange, createQueue and bind functions can be used. For detailed description of how wiring mechanism works have a look here.
int eid = obj.createExchange ("E", Jzmq.SCOPE_GLOBAL, "10.0.0.1:5555");
obj.createQueue ("Q", Jzmq.SCOPE_GLOBAL, "10.0.0.1:5556");
obj.bind ("E", "Q");
Sending a message is pretty straightforward. Message is supplied in form of byte array:
byte msg [] = {1, 2, 3, 4, 5, 6};
obj.send (eid, msg);
Receiving a message is even more simple:
byte [] msg = obj.receive ();
Full sample available here.
Related
I have a project that consists of:
Java server: I accept the connection of N numbers of clients through multithreading.
Client (c++): connects to the Java server.
The dilemma I'm having is how can I send information to the client (from Server) about X and at the same time while that happens make another request. To understand my question better I will give an example:
example: Imagine that I am sending a file from the java server to the client in c++ and while this sending of bytes from the server is taking place, I want to send an echo to the client from the server and receive a response simultaneously while the sending of the file is happening. Is this possible?
2 example: Another case that I would like to address is what would happen if I am receiving bytes on the server from the client and I make another request (echo), so the same socket would be listening x2 (can i read bytes from the same socket simultaneously? What would happen then?):
case 1: receiving bytes
.case 2: listening to the echo
My solution so far has been to use Executors.newSingleThreadExecutor, which allows me to handle each "action" in order one by one. My goal is to be able to perform the actions asynchronously, so that I don't have to wait for another one to finish. How can I achieve this theoretically speaking?
As you're anyway dealing with Java talking to C++, you might as well use something like Google Protocol Buffers to implement an application layer protocol (as Steffen Ullrich suggests), and definitely do not have multiple server threads sending data to a single client.
With GPB, you can define a set of messages, something like (pseudo GPB syntax)
message FileFragment
{
string filename = 1,
integer fragmentFilePosition = 2,
bytes fragmentData = 3
}
message Echo
{
integer echoNum = 1
}
message Protocol
{
oneof
{
FileFragment fragment = 1,
Echo echo = 2,
}
}
With this, you'd create and send Protocol objects through the socket. The client receives those, and either stuffs the fragment data into a file at the position indicated, or deals with the echo.
There are other heterogenous serialisation technologies - ASN.1 is my preferred option, XML can be made to work if you can get good tools, JSON (though that might be a bit tricksie in C++?). I'd default to ASN.1, but GPB is free and enjoys excellent language support.
Java itself is sometimes a nuissance because (AFAIK) it doesn't support unsigned integer types, but as you're in control of both server and client source code (and therefore in control of the procotol between them and the schema that defines it), you can live with it. The nuissance comes if someone else has defined a protocol containing an unsigned 64bit integer type, which then cannot be easily handled in Java.
With Google Protocol Buffers, the wireformat is not self-demarcating, so if you just stuff serialised Protocol objects down the socket the client cannot tell when one ends and another begins. So you'll have to do that separately. A lot of people use something like ZeroMQ (which is message-orientated, not stream-orientated) for this purpose instead of a raw socket.
If you really wanted separate threads sending different Protocol objects through to the client, you'll need a way of guarding against both threads trying to access the socket at the same time (ZeroMQ sockets are not in themselves thread safe), a mutex of some sort.
I have an issue that is driving me crazy! Both design-wise and tech-wise.
I have a need to listen to a LOT of multicast addresses. They are divided into 3 groups per item that I am monitoring/collecting. I have gone down the road of having one process spin-up 100 threads. Each thread uses 2 ports, and three addresses/groups. (2 of the groups are on same port) I am using MulticastChannel for each port, and using SELECT to monitor for data. (I have used datagram but found NIO MulticastChannel much better).
Anyway, I am seeing issues where I can subscribe to about a thousand of these threads, and data hums along nicely. Problem is, after a while I will have some of them stop receiving data. I have confirmed with the system (CentOS) that I am still subscribed to these addresses, but data just stops. I have monitors in my threads that monitor data drops and out-of-order via the RTP headers. When I detect that a thread has stopped getting data, I do a DROP/JOIN, and data then resumes.
I am thinking that a router in my path is dropping my subscription.
I am at my wits end writing code to stabilize this process.
Has anyone ever sent IGMP joins out the network to keep the data flowing? Is this possible, or even reasonable.
BTW: The computer is a HP DL380 Gen-9 with a 10G fiber connection to a 6509 switch.
Any pointers on where to look would really help.
Please do not ask for any code examples.
The joinGroup() operation already sends out IGMP requests on the network. It shouldn't be necessary to send them out yourself, and it isn't possible in pure Java anyway.
You could economize on sockets and threads. A socket can join up to about 20 groups on most operating systems, and if you're using NIO and selectors there's no need for more than one thread anyway.
I have used datagram but found NIO MulticastChannel much better).
I don't know what this means. If you're referring to DatagramSocket, you can't use it for receiving multicasts, so the sentence is pointless. If you aren't, the sentence is meaningless.
I've been thinking about this all day, i dont really think if the Title is the correct one but here it goes, let me explain my situation: Im working on a project, a server made in Java for clients made in Delphi. Conections are good, multiple clients with its own threads, i/o working good. The clients send Strings to the server which i read with BufferedReader. Depending on the reserved words the server receives, it makes an action. Before the client sends the string, it inserts information to a SQL Server database so the server can go and check it after getting the order/command via socket. The server obtains the information in the database, process it, and send it to... let's call it "The Dark Side".
At the moment that the transaction is done, and the info is sent to the dark side, the server inserts the information... cough cough, dark information into a database table so the client can go and take what it requested. BUT, i need to report that to the client! ("Yo, check again the database bro, what you want is there :3").
The conection, the socket is made in other class. Not the one that i want to use to answer to the client, so if i dont have the socket, i dont have the OutputStream, which i need to talk back. That class, the one processing and sending information to the dark side, is going to be working with hundred of transactions in group.
My Issue is here: I can't report to the client that is done because i dont have the sockets references in that class. I instance the clients thread like:
new Client(socket).start();
Objects without references variables, but, i have an option i can take: Store the Sockets and their ip's in a HashMap object at the moment that a new connection is made, like this:
sockets.put(newSocket.getInetAddress().getHostAddress(), newSocket);
Then i can get the socket(so i can get the OutputStream and answer) calling an static method like this:
public static Socket getSocket(String IP) {
Socket RequestedSocket;
RequestedSocket = sockets.get(IP);
return RequestedSocket;
}
But i want you to tell me if there is a better way of doing this, better than storing all of those sockets in a list/hashmap. How can i get those objects without reference variables ? Or maybe thats a good way of doing it and im just trying to overpass the limits.
P.S.: I tried to store the Client objects in the database, serializing them, but the sockets can't be serialized.
Thanks.
This is a design issue for you. You will need to keep track of them somewhere, one solution might be to simply create a singleton class [SocketMapManager] for instance that holds the hashmap, so that you can access it statically from other classes. http://www.javaworld.com/javaworld/jw-04-2003/jw-0425-designpatterns.html
Any solution that tells you to keep a reference to the socket/ connection/ stream is bad -> as that means your connections are going to be held up while the server does its work.
You have a couple of options open
1. have the clients act as servers too. when they connect, they give the server their IP, port and some secret string as part of the hand shake. This means you have control over client code to make this happen.
the servers have a protocol to either take new jobs or check status of old jobs. Client pools the server periodically.
clients connect to database or other application (web service or plain socket like the original app) that connects to data base to get the status of the job. Meaning server gives client a job id.
a socket is open then it one OS resource open. can read up Network Programming: to maintain sockets or not?
All depends on
1. how many client connect at a time/ in 5 minutes.
2. how many seconds/ minutes does one client's request take to process
if number of clients in 5 minutes is maximum (in next 3 years) 300 at a time/ in any 5 minute duration and each request takes at a max 50 seconds to process then a dedicated server with max 50,000 sockets should suffice. Else you need async or more servers (and a DNS/ web server/ port forwarding or other method for load balance)
I'm having a bit of a problem trying to understand what is the flow of the operations, and what exactly you have at disposition. Is this sequence correct?
1. client writes to database (delphi)
2. client writes to server (delphi)
3. server writes to database (java)
4. server writes to client (java)
5. client reads database (delphi)
And the problem is pass 4?
More important: you are saying that there isn't a socket in the Client class, and that you don't have a list of Client too?
Are you able to use the reflection to search/obtain a socket reference from Client?
If you say you don't have the socket, how could it be that you can add that socket in a HashMap?
Last but not least: why do you need to store the socket? Maybe every client opens one connection which is used for multiple requests?
It could be beautiful if all the answers could be conveyed to just one ip:port...
Okay, so I've read around on the Oracal site and some questions on this site. I'm still having kind of a hard time understanding a few things about sockets so I'll see if anyone here could spend the time to explain it to my slow brain. What I'm doing is setting up a chat client and chat server (To learn swing and sockets in one swoop). Despite all the examples I've seen, I still don't quiet grasp how they work. I know how 1 socket with an input stream and 1 socket with an output stream work, but beyond that I'm having trouble understanding because that is as far as most the resources I find explain. Here is my volley of questions regarding this.
If I want to be able to handle input and output to a client at the same time what would I do? Wait for out, then if there is a change in the server switch to input stream and get the changes, then switch back to output stream? Or can I run both an input and output stream at once?
Lets say the server has to handle several clients at once. I'll have to make a socket for each client right? What would you suggest is a good way handle this?
Lets say the client wants to change the IP address or port of their current socket and connect to a different server. Would I just create a new socket, or is there some way to change the current one?
That's the main questions I have. If I can get that much understood I'm pretty sure I could figure out the rest I need on my own.
.
Here's an excellent guide to sockets. It's not "Java sockets" per se, but I think you'll find it very useful:
Beej's Guide to Network Programming
To answer your questions:
Q: If I want to be able to handle input and output to a client at the
same time what would I do?
A: You don't have to do anything special. Sockets are automatically "bi-modal": you can read (if there's any data) or write at any time.
Q: Lets say the server has to handle several clients at once. I'll
have to make a socket for each client right?
A: Actually, the system gives you the socket for each new client connection. You don't "create" one - it's given to you.
Each new connection is a new socket.
Often, your server will spawn a new thread to service each new client connection.
Q: Lets say the client wants to change the IP address or port of their
current socket and connect to a different server. Would I just create
a new socket, or is there some way to change the current one?
A: The client would terminate the existing connection and open a new connection.
I'll try to do my best here, but I really don't think this is the place for that kind of questions:
First of all, you need to understand that sockets are an abstraction of the underlying operating system sockets (unix socket, win socks, etc).
These kinds of sockets are to model connection-oriented services of the transport layer (look at the OSI model). So this means that sockets offer you a stream of bytes from the client and a stream of bytes to the client, so to answer your first question, these streams are independent. Of course it is your responsibility for the design of the protocol you speak over these streams.
To answer your second question you need to know how TCP connections work, basically your server is listening over one or more network interfaces in one port (ports are the TCP addressing mechanism) and can handle a configurable backlog of incoming simultaneous connections. So the answer is, it is common that for any incoming connection a new Thread on the server gets created or obtained from a Thread pool.
To answer your third question, connections are made between hosts, so if you need to change any of them, there will be the need of creating a new connection.
Hope this helps.
Cheers
1.- If I want to be able to handle input and output to a client at the same time what would I do? Wait for out, then if there is a change in
the server switch to input stream and get the changes, then switch
back to output stream? Or can I run both an input and output stream at
once?
It depends on your protocol, if your client start the connection, then your server waits for an input before going to the output stream and sends something. Every connection, being a tcp connection or even working with files have an input stream and an output stream.
2.- Lets say the server has to handle several clients at once. I'll have to make a socket for each client right? What would you suggest is
a good way handle this?
There are different strategies for this that include multithreading so for now focus on streams.Or keep it with one server one client.
3.- Lets say the client wants to change the IP address or port of their current socket and connect to a different server. Would I just
create a new socket, or is there some way to change the current one?
Yes, the definition of a socket is a connection made by an IP address through a specific port if any of those change you need a new socket.
In a socket-based application (client/server), I want to make the server perform as a proxy(manager) to handle several clients, and to get the message from one client and send it to the client, identified by an ID.
How can I know the required client running on different thread, how can I get the socket of the associate client that the id represents?
Just keep an in-memory hashmap of some sort of client-id to the java.net.Socket object that represents that client's socket. You need to come up with some way of assigning client IDs, either client supplied, or server-supplied through some authorization scheme.
When a message comes in for a client ID, grab the socket from the map and send it a message. This map needs to be stored in a singleton-type object, and needs to be properly synchronized. Use a concurrent hash map. Also, socket reads and writes would need to be synchronized if you're going multi-threaded.
I have posted some example code as a github gist. It's a bit different than I explained above. I don't store sockets in the map, I store client handlers which have the socket. Also, socket reads don't need synchronization: each clients has its own thread which is the only thread reading from the socket. Socket writes do need to be synchronized though, because the thread of the sending client is writing to the socket of the receiving client.
You're probably better off using something like JBoss Netty rather than rolling your own though.
you can keep a lot of information about ID so each time it connects you get like the ip and save the thread it is running on and then you use like a hashmap to link the id to all that info then you can easily get the thread it is running on and send the information to the correct client
Save the messages to be delivered into a database, and make your threads check the database for new messages to be delivered to "their" clients on a regular basis.
If you do not want a dedicated database for the messages, build a flat file with simple ClientID->Socket mappings and use it like a "telephone book" kind of lookup system. Depending on the amount of clients you are planning to add, each thread could pre- and regularily reload such a file into it's memory for faster access...