Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java accept()调用时引发套接字关闭异常_Java_Sockets_Port - Fatal编程技术网

Java accept()调用时引发套接字关闭异常

Java accept()调用时引发套接字关闭异常,java,sockets,port,Java,Sockets,Port,我已经找到了解决办法,但还没有找到。我正在尝试编程一个套接字锁,以便一次只能运行一个程序实例,但我得到了一个套接字关闭异常。这是我的SocketCode package utilities; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketAddress; import utilities.enums.ClientType; pub

我已经找到了解决办法,但还没有找到。我正在尝试编程一个套接字锁,以便一次只能运行一个程序实例,但我得到了一个套接字关闭异常。这是我的SocketCode

package utilities;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;

import utilities.enums.ClientType;

public class SocketLocker {
    private final int PORT;
    private ServerSocket serverSocket;
    private Socket clientSocket;

    public SocketLocker(ClientType cType) {
        serverSocket = null;
        clientSocket = null;
        switch (cType)
            {
            case PRODUCER:
                PORT = 7856;
                break;
            case CONSUMER:
                PORT = 7857;
                break;
            default:
                PORT = 7859;
            }
    }

    public boolean getLock() {
        try {
            serverSocket = new ServerSocket(PORT,1);
            clientSocket = serverSocket.accept();
            return true;
        } catch (IOException e) {
            // TODO: log event
            e.printStackTrace();
        }
        return false;
    }

    public void releaseLock() {
        try {
            if (clientSocket != null)
                clientSocket.close();
            if (serverSocket != null)
                serverSocket.close();
        } catch (IOException e) {
            // TODO: Log event

        }
    }
}
下面是我的单元测试代码,我正在运行它来获取异常:

package utilities;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import utilities.enums.ClientType;

public class SocketLockerTest {

    private SocketLocker producerLocker;
    private SocketLocker consumerLocker;

    @Before
    public void start() {
        producerLocker = new SocketLocker(ClientType.PRODUCER);
        consumerLocker = new SocketLocker(ClientType.CONSUMER);
    }

    @Test(timeout = 10000)
    public void lockProducer() {
        assertTrue(producerLocker.getLock());
    }

    @Test(timeout = 10000)
    public void lockConsumer() {
        assertTrue(consumerLocker.getLock());
    }

    @Test(timeout = 10000)
    public void lockProducerTwice() {
        producerLocker.getLock();
        assertFalse(producerLocker.getLock());
    }

    @Test(timeout = 10000)
    public void lockSeparately() {
        producerLocker.getLock();
        assertTrue(consumerLocker.getLock());
    }

    @Test(timeout = 10000)
    public void lockProdcuerSeparateObject(){
        producerLocker.getLock();
        assertFalse(new SocketLocker(ClientType.PRODUCER).getLock());
    }

    @After
    public void finish() {
        producerLocker.releaseLock();
        consumerLocker.releaseLock();
    }
}
java.net.SocketException: socket closed
    at java.net.PlainSocketImpl.socketAccept(Native Method)
    at java.net.PlainSocketImpl.accept(Unknown Source)
    at java.net.ServerSocket.implAccept(Unknown Source)
    at java.net.ServerSocket.accept(Unknown Source)
    at utilities.SocketLocker.getLock(SocketLocker.java:34)
    at utilities.SocketLockerTest.lockProducer(SocketLockerTest.java:25)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.FailOnTimeout$1.run(FailOnTimeout.java:28)
这里有一个例外:

package utilities;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import utilities.enums.ClientType;

public class SocketLockerTest {

    private SocketLocker producerLocker;
    private SocketLocker consumerLocker;

    @Before
    public void start() {
        producerLocker = new SocketLocker(ClientType.PRODUCER);
        consumerLocker = new SocketLocker(ClientType.CONSUMER);
    }

    @Test(timeout = 10000)
    public void lockProducer() {
        assertTrue(producerLocker.getLock());
    }

    @Test(timeout = 10000)
    public void lockConsumer() {
        assertTrue(consumerLocker.getLock());
    }

    @Test(timeout = 10000)
    public void lockProducerTwice() {
        producerLocker.getLock();
        assertFalse(producerLocker.getLock());
    }

    @Test(timeout = 10000)
    public void lockSeparately() {
        producerLocker.getLock();
        assertTrue(consumerLocker.getLock());
    }

    @Test(timeout = 10000)
    public void lockProdcuerSeparateObject(){
        producerLocker.getLock();
        assertFalse(new SocketLocker(ClientType.PRODUCER).getLock());
    }

    @After
    public void finish() {
        producerLocker.releaseLock();
        consumerLocker.releaseLock();
    }
}
java.net.SocketException: socket closed
    at java.net.PlainSocketImpl.socketAccept(Native Method)
    at java.net.PlainSocketImpl.accept(Unknown Source)
    at java.net.ServerSocket.implAccept(Unknown Source)
    at java.net.ServerSocket.accept(Unknown Source)
    at utilities.SocketLocker.getLock(SocketLocker.java:34)
    at utilities.SocketLockerTest.lockProducer(SocketLockerTest.java:25)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.FailOnTimeout$1.run(FailOnTimeout.java:28)

您的测试在超时时失败。当你打电话的时候

 @Test(timeout = 10000)
    public void lockProducer() {
        assertTrue(producerLocker.getLock());
    }
如果在指定端口上打开服务器套接字,然后等待连接进入,会发生什么情况

serverSocket = new ServerSocket(PORT,1);
clientSocket = serverSocket.accept();

因此,您的代码将等待accept直到超时,因为您没有启动连接尝试。

您的测试在超时时失败。当你打电话的时候

 @Test(timeout = 10000)
    public void lockProducer() {
        assertTrue(producerLocker.getLock());
    }
如果在指定端口上打开服务器套接字,然后等待连接进入,会发生什么情况

serverSocket = new ServerSocket(PORT,1);
clientSocket = serverSocket.accept();

因此,您的代码将等待accept直到超时,因为您没有启动连接尝试。

如果服务器套接字的目的只是防止两个实例同时运行,那么在其上接受连接根本没有意义。只需删除客户机套接字变量和accept()调用。您实现的不是锁,而是实际上的死锁。

如果服务器套接字的目的只是防止两个实例同时运行,那么接受它上的连接根本没有意义。只需删除客户机套接字变量和accept()调用。您实现的不是锁,而是实际上的死锁。

@matheszabi这不是一个好答案为什么?这样的说法对任何人都是毫无用处的。类似地,无法解释的否决票基本上只是破坏网站。事实上,答案不仅纠正了OP引用的测试问题,而且纠正了其应用程序中的一个主要设计缺陷。如果你不明白你应该问问题。“当你应该听的时候,你在说话。”马塞萨比我认为这是一个很好的回答。这让我明白了我的问题所在,也指引了我找到解决方案的正确方向。@ReidMac感谢您的确认。@matheszabi这不是一个好答案为什么?这样的说法对任何人都是毫无用处的。类似地,无法解释的否决票基本上只是破坏网站。事实上,答案不仅纠正了OP引用的测试问题,而且纠正了其应用程序中的一个主要设计缺陷。如果你不明白你应该问问题。“当你应该听的时候,你在说话。”马塞萨比我认为这是一个很好的回答。这让我明白了我的问题所在,并指引我找到了正确的解决方案。@ReidMac感谢您的确认。