AsynchronousServerSocketChannel.accept is only accepting a one connection - java

I have a small server setup where I'm trying to use event based connection sockets, so that a handler is called on each incoming connection. It works great for the first connection, but no new connections are accepted after the first one.
I just close the client connection when it comes in for simplicity. Also, yes the server is still running after the first connection, it doesn't terminate.
Here is the code:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class ServerTest
{
static CompletionHandler<AsynchronousSocketChannel, Object> handler =
new CompletionHandler<AsynchronousSocketChannel, Object>() {
#Override
public void completed(AsynchronousSocketChannel result, Object attachment) {
System.out.println(attachment + " completed with " + result + " bytes written");
try {
result.close();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void failed(Throwable e, Object attachment) {
System.err.println(attachment + " failed with:");
e.printStackTrace();
}
};
public static void main(String[] args) throws Exception
{
AsynchronousChannelGroup group = AsynchronousChannelGroup.withThreadPool(Executors.newSingleThreadExecutor());
System.out.println("STARTING");
AsynchronousServerSocketChannel ssc =
AsynchronousServerSocketChannel.open(group).bind(new InetSocketAddress("localhost", 9999));
System.out.println("BOUND");
ssc.accept(ssc, handler);
group.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
}
}

public abstract void accept(A attachment, CompletionHandler handler)
This method initiates an asynchronous operation to accept a connection made to this channel's socket. The handler parameter is a completion handler that is invoked when a connection is accepted (or the operation fails). The result passed to the completion handler is the AsynchronousSocketChannel to the new connection.
Read more here
This means that it initializes an asynchronous thread to accept incoming connections. This also means that it'll take the first connection and forward it to the asynchronous thread and then wait for more connections. To allow more clients to connect you must invoke an accept method inside of the overwritten completed function as well.
Here is an example,
server.accept(null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
#Override
public void completed(AsynchronousSocketChannel chan, Void attachment) {
System.out.println("Incoming connection...");
server.accept(null, this); //add this
//...
It should be noted that for every client, a new AsynchronousSocketChannel result is produced. That being said if you were to print out 'chan', it'll result in different objects.
Distinct client objects

Related

How to terminate a thread that has been blocked for too long due to Socket.accept()?

public class Slave implements Runnable {
public ServerSocket slaveSocket;
public Slave(ServerSocket sk) {socket = sk;}
#Override
public void run() {
Socket client = slaveSocket.accept(); // slave will wait to serve a client
// more code...
Socket clientPart2 = slaveSocket.accept();
// more code...
}
}
public class Server {
public static void main(String[] args) {
// for example only, incomplete code
ServerSocket serverSocket = new ServerSocket(0); // a client connect to 8088
Slave slave = new Slave(serverSocket);
new Thread(slave).start(); // slave serve the current client, the server wait for new client
// send new slave's port to client ...
}
}
So I have a server that serves multiple clients at once. Whenever a client connects, the server will create a new Slave, send the IP/port of that slave to the client, then the client will work with the slave.
However, if the client receives the slave's address then do nothing (or quit) (Edit: it means the client and server are connected but the client do nothing, because for example the user goes for lunch) slaveSocket.accept() causes that slave Thread to run forever, which is wasteful.
I want the slave thread to exit after 30 second of waiting for slaveSocket.accept(). Since slaveSocket.accept() is blocking, I cannot do that from inside the void run().
What is the correct, clean way to solve this problem? Thank you.
Edit 1: a ServerSocket is passed to the slave because the client can have multiple processes that will connect to that slave. So it doesn't just perform one function.
If you set a timeout with setSoTimeout and no client connects, ServerSocket.accept will throw an exception. You can catch this exception.
To set a timeout of 30 seconds, use:
serverSocket.setSoTimeout(30000)
Non-blocking I/O:
Take a look at AsynchronousServerSocketChannel's accept method which returns a Future. Then the Future has a getter with timeout which can do what you are asking.
Note: you may read a related tutorial.
Then the getter will return an AsynchronousSocketChannel which can be converted back to blocking via the corresponding Channels.newInputStream and Channels.newOutputStream methods to be used with the blocking approach in the worker threads.
Blocking I/O:
I think you actually meant on how to implement a server which accepts clients sequentially and serves them in parallel, with blocking I/O. If that is the case, then you may take a look at the following example:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Objects;
public class Main {
public static class Worker implements Runnable {
private final Socket sck;
private OutputStream os;
private InputStream is;
public Worker(final Socket sck) {
this.sck = Objects.requireNonNull(sck);
}
#Override
public void run() {
try {
os = sck.getOutputStream();
is = sck.getInputStream();
//ALL the work with the client goes here, unless you need more than one connections with him.
}
catch (final IOException iox) {
System.err.println(iox);
}
finally {
try { is.close(); } catch (final IOException | RuntimeException x) {}
try { os.close(); } catch (final IOException | RuntimeException x) {}
try { sck.close(); } catch (final IOException | RuntimeException x) {}
}
}
}
public static void main(final String[] args) {
ServerSocket srv = null;
try {
srv = new ServerSocket(8088);
while (true)
new Thread(new Worker(srv.accept())).start();
}
catch (final IOException iox) {
System.err.println(iox);
}
finally {
try { srv.close(); } catch (final IOException | RuntimeException x) {}
}
}
}

Why is my java program spinning after I hit server.stop(0)?

I wrote a basic java server class. When it handles the "shutdown" request, it calls server.stop(0) and the spins in place. Why is this happening?
I copied most of the code from this StackOverflow post.
The only significant modification to this code is that I added the server.stop(0).
Other facts: I am running this using java 8 and I am running this through IntelliJ.
package good.question.ask.questions.stackoverflow;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
public class ServerTester2
{
private HttpServer server = null;
public static void main(String[] args) throws Exception {
ServerTester2 serverTester2 = new ServerTester2();
serverTester2.start();
}
void start()
{
try {
server = HttpServer.create(new InetSocketAddress(8000), 0);
} catch (IOException e) {
e.printStackTrace();
}
server.createContext("/shutdown", new MyHandler());
server.setExecutor(null); // creates a default executor
server.start();
}
class MyHandler implements HttpHandler
{
#Override
public void handle(HttpExchange t) throws IOException
{
String response = "This is the response";
t.sendResponseHeaders(200, response.length());
OutputStream os = t.getResponseBody();
os.write(response.getBytes());
os.close();
t.close();
System.out.println("Stopping Server...");
stop();
System.out.println("Server Stopped!");
}
}
void stop()
{
server.stop(0);
}
}
Currently, the server returns a response message to the client (I tested that using postman), and then prints "Stopping Server" to the console. After that, the server object seems to be shut down, because when I send it more requests it doesn't respond to them, however, the thread running the server continues to spin.
Minimally, I expected the server to reach this line of code
System.out.println("Server Stopped!");
but it never does.
More to the point, I expected the server thread to terminate but instead, it just spins.
Why is this happening? (Do I have a deadlock in the code somewhere?)
Is there a better way to handle server shutdown (using the httpserver library)?

Android: How to make a thread which waits for server messages and updates the UI?

i have made a java server and java client programms that communicate with TCP sockets sending String messages. Those java programs work perfectly. The client logic is that it has a UI and a thread, which is waiting all the time for new messages and updates the UI accordingly what message it recieved (e.x. add buttons,set buttons visible, change texts).
Now, im totally new to android and i want to make an equal client for android but i faced those problems:
1) I can't update the UI from a background thread just passing parameters(like java).
2) I want that one thread to update 2 or 3 Activies(i need 2-3 because the lack of screen space)
I have read about AsyncTask but they say it is recommended for sort tasks, then i read about threads with handlers but they say is difficult to work with and i got confused. So my question is what method should i use on android to achieve that "message listener/UI updater" thread.
UPDATE: Ok, i used threads and handlers and my main activity got updated, but now how i can update the second Activitie from that thread too??
well, you can start a thread for some specific time and after that check if there is any message from server, if not, restart the thread or else do your work. hope this is helpful.
you can implement it like this
package com.example.a41264.myapplication;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* Created by 41264 on 04/23/17.
*/
public class Client implements Runnable{
final CopyOnWriteArrayList<MsgListener> listeners = new CopyOnWriteArrayList<>();
#Override
public void run() {
Socket socket = new Socket();
try {
int yourPort = 0;
SocketAddress address = new InetSocketAddress("your ip",yourPort);
socket.connect(address);
int your_buffer_size = 1024;
byte[] buffers = new byte[your_buffer_size];
InputStream is = socket.getInputStream();
int resultLength;
String msg;
while(true){
resultLength = is.read(buffers);
msg = new String(buffers,0,resultLength);
if(listeners.size() != 0){
for(MsgListener msgListener: listeners){
msgListener.onMsgRecived(msg);
}
}
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void addListener(MsgListener listener){
listeners.add(listener);
}
public void removeListener(MsgListener listener){
listeners.remove(listener);
}
public interface MsgListener{
void onMsgRecived(String msg);
}
}
and do your work at activity like this
package com.example.a41264.myapplication;
import android.app.Activity;
import android.util.Log;
/**
* Created by 41264 on 04/23/17.
*/
public class YourActivity extends Activity{
private Client client; //you need to get your clent;
private Client.MsgListener msgListener = new Client.MsgListener() {
#Override
public void onMsgRecived(final String msg) {
runOnUiThread(new Runnable() {
#Override
public void run() {
//do your own work in main thread
Log.i("tag",msg);
}
});
}
};
#Override
protected void onRestart() {
super.onRestart();
client.addListener(msgListener);
}
#Override
protected void onStop() {
super.onStop();
client.removeListener(msgListener);
}
}

Java timeout since last received datagram

I have the following code in my main application:
package acast;
import java.net.SocketException;
import java.util.concurrent.ConcurrentLinkedQueue;
public class ACast {
private ConcurrentLinkedQueue<String> queue;
public ACast() throws SocketException{
queue = new ConcurrentLinkedQueue<String>();
UDPServer srv = new UDPServer(4321);
srv.addUDPacketListener(new UDPPacketListener() {
#Override
public void onPacketReceived(String packet) {
ACast.this.queue.offer(packet);
}
});
srv.start();
}
public static void main(String[] args) throws SocketException {
try{
new ACast();
}
catch(SocketException e){
//e.printStackTrace();
System.out.println("Socket allready opened. Can't start application");
System.exit(1);
}
}
}
My UDPServer extends Thread and calls onPacketReceived every time it receives an UDP datagram. I want my main app to do something every time a configured timeout passes since the last received datagram. I would like to avoid running a Thread that just checks the timeout from second to second. I would like to start a countdown thread exactly on the moment of the last received datagram and cancel any other ongoing timeout threads if available. Any help ?
A simple solution would be to start a Timer with the timeout task, and every time a new datagram is received, cancel the currently running timer and start a new one.
I would lose the asynchronicity altogether, and use blocking I/O with a read timeout.

How to prevent this Java code from hanging

I have a list of proxies to test if they are HTTP or Socks proxies, but the Java code below hangs when it calls the connection.getContent() or connection.getInputStream(). I observed that this issue occur when the proxy server fail to respond and the code blocks waiting for response from server, How can I prevent this code from hanging/blocking forever when the server fail to respond, so that the next proxy can be checked.
import java.io.*;
import java.net.*;
import java.util.*;
public class ProxyTest {
public static void main(String[] args) throws IOException {
InetSocketAddress proxyAddress = new InetSocketAddress("myproxyaddress", 1234);
Proxy.Type proxyType = detectProxyType(proxyAddress);
}
public static Proxy.Type detectProxyType(InetSocketAddress proxyAddress) throws IOException {
URL url = new URL("http://www.google.com/");
List<Proxy.Type> proxyTypesToTry = Arrays.asList(Proxy.Type.SOCKS, Proxy.Type.HTTP);
for(Proxy.Type proxyType : proxyTypesToTry) {
Proxy proxy = new Proxy(proxyType, proxyAddress);
URLConnection connection = null;
try {
connection = url.openConnection(proxy);
connection.setConnectTimeout(10000);
connection.setReadTimeout(10000);
connection.getContent();
//connection.getInputStream();
return(proxyType);
}
catch (SocketException e) {
e.printStackTrace();
}
}
return(null);
}
}
To do things in parallel, use threads.
for(Foo f : foos){
Thread t = new Thread(new Runnable(){
#Override
public void run(){
// blocking call
}
});
t.start();
}
Better yet, make use of one of the data structures in the java.util.concurrent package.
I believe there is no and simple straight solution for this. The answer depends on JDK version, implementation and runtime environment. For more details please see Java URLConnection Timeout.

Categories

Resources