Communiation with multiple clients via Sockets - java

I have a Server Socket and 3-4 android devices as clients. I'm using TCP/IP for communications. Which is the best method. Should I use multiple ports for each client? Or should I use same port. If using same function then how should I identify the communication addressed to different devices?

No, you do not need several ports.
ServerSocket server = new ServerSocket(port);
while (true)
{
Socket socket = server.accept();
// do something with this socket - aka 1 client
new SomeClientClass(socket);
InputStream in = socket.getInputStream();
in.read(byte[]);
OutputStream out = socket.getOutputStream;
// out will only write response to its own client.
// when this new SomeClientClassis created, method returns to this point
// in while loop and waits for the next client
}

You can use one port. The client can send you its id. If it can't you can look at the clients IP address to workout which one it is.
There are thousands of TCP client/server code examples on the web, but I would start with the sample code which comes with the JDK,

Related

How server-socket with more than one backlog works?

I'm new to socket programming, I have problem in understanding serversocket.
assume we create a serversocket like this:
loadbalancerSocket = new ServerSocket(port, 20);
connection = loadbalancerSocket.accept();
and then after some stuff, write something in its buffer:
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream()));
writer.write("Hello!");
writer.flush();
writer.close();
My question is : How the connection understand which client should get the response of server? our backlog is 20 , and 20 client can connect to the server socket at the same time(As I understood).
In your example the first connected client gets the response. The backlog parameter does not mean number of clients that can connect in parallel. It is the maximum number of clients waiting for accepting connection.
The ServerSocket is not connected to any particular client. The connected socket is the socket returned from accept(). If you want to handle multiple clients in parallel you have to call accept() multiple times and handle connections separately. You can create a special thread for each connection for example.
accept() is typically called in a loop and the newly created connected socket returned from accept() is typically passed to a handler that is responsible for particular client.

multiple sockets between server and client

I have a java server aplication which comunicate with multiple clients via SocketChannel. On this channel, client sends a request and server sends an answer. Now I want add feature that server can sends file to the client. I don't want send it via the socket whith I am using for comunication so is good idea to have more sockets between one client and one server? If yes how to handle them? Have I use something like this?
SocketChannel socket = serverSocket.accept()
if(!addressSet.contains(socket.address)) {
it is comunicate socket
}
else {
it is date transfer socket
}
or is there some better way?
Create a new ServerSocket on a random port once you accept a client connection, then tell him that port number. He should then connect to that as the data connection. Then,have the server accept one connection from it, which better be from him, then close that ServerSocket. It's not foolproof but it's reasonably strong.
Yes there is a better way.
Use ServerSocketChannel and the method public abstract SocketChannel accept() throws IOException

Java multiple multicast sockets in same group on same host and port

I'm using multicast to implement a simple discovery service. Several instances on the application must be able to run on the same host, I therefore end up with several multicast sockets that are members of the same group on the same host.
On Linux, this works as expected. Every instance of the application on a host receives the messages sent to the multicast address.
On Windows however, only the first application to join the multicast group receives the messages sent.
Here is the code I'm using to create my multicast socket:
socket = new MulticastSocket(PORT);
InetAddress group = InetAddress.getByName(ADDRESS);
socket.joinGroup(group);
socket.setTimeToLive(TTL);
Is there some option I need to set? I've tried scouring the API but I can't find anything.
EDIT: According to this website, I need to set SO_REUSEADDR, but this can only be set before the socket binds. It seems the constructor for MulticastSocket seems to bind the socket upon creation.
you do this by creating the socket with no arguments and then call bind on that object.
socket = new MulticastSocket();
socket.setReuseAddress(true);//redundant, already set with empty constructor
SocketAddress sockAddr = new InetSocketAddress(PORT);
socket.bind(sockAddr);
InetAddress group = InetAddress.getByName(ADDRESS);
socket.joinGroup(group);
socket.setTimeToLive(TTL);

Sending data via the network

I would like to create a program that will emulate a device connected to the network and send signals through a specific port.
The device is connected to the network and sends data through a port. On the server(or computer) I have running the CPR Manager v.4.3.0.1 from Lantronix that will associate the IP:PORT to a virtual COM port on the computer. I have a java program that listens to the COM ports and performs an action, this works great with the device.
I tried writing a java app using the Socket class to perform the connection but it was un successful, on the CPR side it only registers a Disconnect when the very first line is executed:
Socket socket = new Socket("192.168.1.160", 8888);
I also tried it using the UDP method and no message whats so ever is recorded.
Any help would be greatly appreciated. Also if there is no possible solution for Java then any other language would do fine.
EDIT:
Here is the Java code where I am attempting to send the data
public static void main(String[] args){
try{
Socket socket = new Socket("192.168.1.160", 8888);
if(socket.isConnected()){
System.out.println("It is connected.");
socket.setKeepAlive(true);
System.out.println(socket.isBound());
}else{
System.out.println("It is not connected.");
}
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in =
new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String msg = "32";
for(int i = 0; i < 50; i++){
out.println(msg);
}
//Receive a reversed message
msg = in.readLine();
System.out.println("Server : " + msg);
}catch(Exception ioe){
ioe.printStackTrace();
}
}
Thanks.
Update
I got in contact with some people of the devices and they showed me that there is a way to communicate straight via a TCP/IP connection sending there ASCII Command Protocols. This would allow more in depth control at every level.
So, now I am writing a java program that can communicate using these protocols.
Because, I am not using a comm port anymore I am tying to emulate the baud rate, data bits, stop bit stuff. I will post when I have some that works.
Thanks for all the help.
if the product you are using is forwarding the traffic to a COM port should you be listening on the COM port not on a network connection. Sockets are for network traffic. A quick google search resulted this for me.
How to send data to COM PORT using JAVA?
Maybe that will help?

What will happen to a TCP/UDP serversocket when I switch wifi network?

what will happen to the serversocket in my app when I suddenly change the wifi network? I guess it will shut down since my device will get a new IP, at least in TCP, is the UDP MulticastSocket prone to this as well? And how to end the previous Server socket thread and start a new one when the network changes? One solution is using time outs, another is using a flag that will indicate whether the infinite loop should end or not but since listening to a socket is a blocking function it will produce an exception/error anyways.
Any thoughts will be appreciated! :)
EDIT: sample of my server thread.
ServerSocket ss = new ServerSocket(4445);
while(true){
Socket socket = ss.accept();
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
Object obj = in.readObject();
Log.i("TAG", "Received: " + obj.toString());
in.close();
socket.close();
}
TCPIP connection will break. So client would have to connect again.
UDP will be ok provided your IP does not change after reconnection. Of course if you transmit UDP its not going to make a difference for that machine.
You should get an exception in case of TCPIP which you can handle.
UDP sockets that are not bound to the address will remain open, as they are stateless. TCP listening sockets not bound to the address will remain open as well.
Conntected TCP sockets may be severed (RST) or just linger until a timeout hits.
It is a little known fact that IP mandates it that a device by default will accept packets directed to any address it has configured on any interface, no matter on which interface the packet arrives. If this were not so, routing would be broken. One can use packet filters to filter out packets with non-matching addresses depending on the interface.

Categories

Resources