Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Socket closed but sends SYN_SENT after a few seconds #993

Closed
ttcds opened this issue Jul 22, 2024 · 6 comments
Closed

Socket closed but sends SYN_SENT after a few seconds #993

ttcds opened this issue Jul 22, 2024 · 6 comments

Comments

@ttcds
Copy link

ttcds commented Jul 22, 2024

After closing a ZMQ.Socket like below (simplified code) a few seconds later a SYN_SENT is send which causes an underlying tcp socket to connect again. And when starting a new thread with a new ZMQ.Socket there are 2 tcp sockets open to the endpoint while the first one should have never reconnected again by itself.

Code

public class Main
{
    static ZContext context = new ZContext();

    public static void main(String[] args) throws InterruptedException
    {
        var runner = new RemoteDealer.Runner();
        var runnerThread = new Thread(runner);
        runnerThread.start();

        Thread.sleep(5000);

        runnerThread.interrupt();

        runner = new Runner.Runner();
        runnerThread = new Thread(runner);
        runnerThread.start();
        Thread.sleep(6000);
    }

    static class Runner implements Runnable
    {
        ZMQ.Socket socket;

        @Override
        public void run()
        {
            String endpoint = "tcp://" + remoteIp + ":60000";

            try
            {
                socket = context.createSocket(SocketType.DEALER);
                socket.setTCPKeepAlive(1);
                socket.setTCPKeepAliveCount(1);
                socket.setTCPKeepAliveIdle(8);
                socket.setTCPKeepAliveInterval(5);
                socket.setLinger(0);
                socket.setHandshakeIvl(0);
                socket.setReconnectIVL(30000);
                socket.setSendTimeOut(5000);
                socket.setReceiveTimeOut(5000);
                socket.connect(endpoint);

                ZMQ.Poller poller = context.createPoller(6);
                poller.register(socket, ZMQ.Poller.POLLIN);

                while (!Thread.currentThread().isInterrupted())
                {
                    poller.poll();
                    try
                    {
                        if (poller.pollin(0))
                        {
                            ...
                        }
                    } catch (Exception ex)
                    {
                        ex.printStackTrace();
                    }
                }
            }
            catch (Exception ex)
            {
                ex.printStackTrace();
            }
            finally
            {
                socket.disconnect(endpoint);
                socket.close();
            }
        }
    }
}
public static void main(String[] args)
{
    var router = "tcp://*:" + 60000;

    var context = new ZContext();

    ZMQ.Socket routerSocket = context.createSocket(SocketType.ROUTER);
    routerSocket.setTCPKeepAlive(1);
    routerSocket.setTCPKeepAliveCount(1);
    routerSocket.setTCPKeepAliveIdle(8);
    routerSocket.setTCPKeepAliveInterval(5);
    routerSocket.setLinger(0);
    routerSocket.setHandshakeIvl(0);
    routerSocket.setSendTimeOut(5000);
    routerSocket.setReceiveTimeOut(5000);
    routerSocket.bind(router);

    var poller = context.createPoller(6);
    poller.register(routerSocket, ZMQ.Poller.POLLIN);

    var runnerThread = new Thread(() -> {
        try
        {
            while (!Thread.currentThread().isInterrupted())
            {
                poller.poll();

                if (poller.pollin(0))
                {
                    ...
                }
            }
        } catch (Exception ex)
        {
            ex.printStackTrace();
        } finally
        {
            routerSocket.close();
        }
    });

    runnerThread.start();
    Thread.sleep(1000000);
}

After a few disconnects and reconnects the output of netstat looks like this:

tcp        0      0 src:35476    dst:60000 ESTABLISHED
tcp        0      0 src:35480    dst:60000 ESTABLISHED
tcp        0      0 src:35482    dst:60000 ESTABLISHED
tcp        0      0 src:35484    dst:60000 ESTABLISHED
@trevorbernard
Copy link
Member

trevorbernard commented Jul 25, 2024

@ttcds Thank you for the test case but we'll need more information about the where the server and client is running on. What version of Linux and the kernel are you running?

@ttcds
Copy link
Author

ttcds commented Jul 29, 2024

@trevorbernard I am using a Yocto build (dunfell) and using kernel 5.4.147.

The situation is as follows:

  • There is a disconnect (plugging out ethernet cable) so I interrupt the thread
  • Socket disconnects and closes properly
  • Socket gone from netstat also
  • When plugging the ethernet cable back in and restarting the thread there are now multiple connections

@trevorbernard
Copy link
Member

What version of the Java SDK?

@ttcds
Copy link
Author

ttcds commented Aug 7, 2024

Openjdk 17.0.10

@trevorbernard
Copy link
Member

trevorbernard commented Aug 14, 2024

@ttcds is the issue that there are extraneous SYN packets sent or that the ROUTER maintains an established connection with a closed socket?

@trevorbernard
Copy link
Member

trevorbernard commented Sep 18, 2024

I worked with the Teletask team and wasn't able to recreate this issue reliably but we did identify a Socket leak using the built in monitor API. Closing and will create a new issue.

#999

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants