How to prevent this Java code from hanging - java

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.

Related

Java chat program works on localhost, but not when hosting on Heroku

Long story short, I stole and modified some code from GeeksForGeeks to practice with sockets. Running code modified for localhost works fine on desktop, but when modifying and attempting to host on Heroku, I can't seem get a connection between the server and client. Server appears to launch and run fine on Heroku, and logs connections that I'm not even making (no idea where those are coming from). Client on the other hand seems to connect, but then doesn't do anything when I send a message. Server doesn't even log my attempted connection, so I know it probably isn't even connecting.
Server code: https://github.com/RenegadeB5/socket in /src/main/java/
Client Code:
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class Client
{
public static void main(String args[]) throws UnknownHostException, IOException
{
Scanner scn = new Scanner(System.in);
// establish the connection
Socket s = new Socket("<my app name>.herokuapp.com", 80);
// obtaining input and out streams
DataInputStream dis = new DataInputStream(s.getInputStream());
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
// sendMessage thread
Thread sendMessage = new Thread(new Runnable()
{
#Override
public void run() {
while (true) {
// read the message to deliver.
String msg = scn.nextLine();
try {
// write on the output stream
dos.writeUTF(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
// readMessage thread
Thread readMessage = new Thread(new Runnable()
{
#Override
public void run() {
while (true) {
try {
// read the message sent to this client
String msg = dis.readUTF();
System.out.println(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
sendMessage.start();
readMessage.start();
}
}
I've tried so many different combinations and solutions, and can't find any examples of this being done before. I'd like to know what I'm doing wrong so that I can move on from this headache. Thanks in advance!
Java Socket and ServerSocket use TPC, which is not supported for free by Heroku. As a result, the server will run fine, but anything being sent via TCP, including connection attempts, will not make it to your server unless they are done via http.

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

Socket.io Java client automatically disconnects after a few seconds

I am trying to keep a connection between the server and my java client alive. This is my code:
import io.socket.client.*;
import io.socket.client.IO;
import java.net.URISyntaxException;
public class Main {
public static void main(String[] args) throws URISyntaxException, InterruptedException {
IO.Options opts = new IO.Options();
opts.reconnection = true;
Socket socket = IO.socket("http://localhost:3000", opts);
socket.connect();
socket.on("disconnect", args123 -> System.out.println("disconnect"));
Thread t = new Thread(new test(socket));
t.start();
}
}
class test implements Runnable{
private Socket socket;
public test(Socket socket){
this.socket = socket;
}
#Override
public void run() {
try {
Thread.sleep(3000);
socket.emit("test","test");
System.out.println("test");
} catch (Exception e) {
e.printStackTrace();
}
}
}
The test event in the thread does not arrive on the server because my client disconnects automatically.
I also tried this option for my server:
{transports: ['websocket'], upgrade: false}
or setting the ping interval and timeout interval
I believe your server is a "http" server. So that, you can keep connection alive, but you have to tell this to the server. This is done by request headers. So, simply, I would send "Connection: keep-alive" header. Moreover, your code doesn't look like an http implementation. So, first you should start implementing "http" protocol, then send "Connection: keep-alive" header.
Trying to keep a connection alive from client is not enough to keep really it alive. You have to agree with server.
Check how you can keep alive a http connection on https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive

Netty 4 creating multiple connections from client

I am trying to create multiple client connection to a java based socket server from another machine. Both server and client use Netty 4 for NIO. On server side, I used boss and worker group and its able to receive and server 100000 concurrent connection on a single linux box (after setting kernel parameters and ulimit).
However, I end up creating a new thread per connection on client side and that caused JVM thread limit exception.
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
​
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
​
public class TelnetClient
{
private Bootstrap b;
private NioEventLoopGroup loopGroup;
private TelnetConnectionInitializer tci;
​
​
public static void main(String[] args) throws Exception
{
System.out.println("TelnetClient:main:enter " + args[0]);
​
TelnetClient tc = new TelnetClient();
​
String countStr = args[0]; //number of connections to make
int count = Integer.valueOf(countStr);
​
for (int i=0; i < count; i++)
{
params.add(String.valueOf(i));
Runnable r = new ClientThread(tc);
new Thread(r).start();
}
​
System.out.println("TelnetClient:main:exit");
}
​
public TelnetClient()
{
System.out.println("TelnetClient:TelnetClient");
b = new Bootstrap();
loopGroup = new NioEventLoopGroup();
b = b.group(loopGroup);
b = b.channel(NioSocketChannel.class);
tci = new TelnetConnectionInitializer();
}
​
public void connect(String host, int port) throws Exception {
System.out.println("TelnetClient:connect:enter");
​
try {
b.handler(tci).connect(host, port).sync().channel().closeFuture().sync();
} finally {
b.group().shutdownGracefully();
}
System.out.println("TelnetClient:connect:exit");
}
}
​
/// Creating a new thread per connection,
/// Which seems the culprit of JVM exception, but couldn't found a way to implement boss / worker like solution on client side.
class ClientThread implements Runnable
{
TelnetClient myTc;
​
public ClientThread(TelnetClient tc)
{
myTc = tc;
}
​
public void run()
{
System.out.println("ClientThread:run"); ​
try
{
myTc.connect("192.168.1.65", 4598); //Server running on different machine in local network
} catch (Exception e)
{
e.printStackTrace();
}
}
}
Can someone point me, how I can create multiple connections from client side using Netty, without spawning new thread per client. I tried one and only snippet found for similar condition in another post on stack overflow but in that, for me execution paused (entered into an infinite wait state) after first successful connection itself.
Thanks
The code looks to be correct apart from two important things - you have to share netty context by all the clients and work asynchronously.
I.e. initialize EvenetLoopGroup at the beginning and pass this single instance to every call to Bootstrap.group() for each client.
For asynchronous aproach avoid sync() on connect() future (not that much important) and mainly on close() future. The latter the code being suspended until the connection is closed.

Categories

Resources