java - 打开转换 java.net.SocketException : Permission denied

标签 java sockets openshift openshift-cartridge

我使用的是 Java8 并且有一个聊天服务器,可以在我的本地主机 上完美运行,但是当我将它部署到 OpenShift 服务器时,出现以下错误:

java.net.SocketException: Permission denied

2016-09-05 10:36:11,300 INFO  [stdout] (Thread-125) Starting Chat server on localhost:8000 ...
2016-09-05 10:36:13,194 ERROR [stderr] (Thread-125) Exception in thread "Thread-125" java.net.SocketException: Permission denied
2016-09-05 10:36:13,194 ERROR [stderr] (Thread-125)     at sun.nio.ch.Net.bind0(Native Method)
2016-09-05 10:36:13,195 ERROR [stderr] (Thread-125)     at sun.nio.ch.Net.bind(Net.java:433)
2016-09-05 10:36:13,195 ERROR [stderr] (Thread-125)     at sun.nio.ch.Net.bind(Net.java:425)
2016-09-05 10:36:13,195 ERROR [stderr] (Thread-125)     at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
2016-09-05 10:36:13,195 ERROR [stderr] (Thread-125)     at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
2016-09-05 10:36:13,196 ERROR [stderr] (Thread-125)     at io.netty.channel.socket.nio.NioServerSocketChannel.doBind(NioServerSocketChannel.java:125)
2016-09-05 10:36:13,196 ERROR [stderr] (Thread-125)     at io.netty.channel.AbstractChannel$AbstractUnsafe.bind(AbstractChannel.java:476)
2016-09-05 10:36:13,196 ERROR [stderr] (Thread-125)     at io.netty.channel.DefaultChannelPipeline$HeadHandler.bind(DefaultChannelPipeline.java:1000)
2016-09-05 10:36:13,196 ERROR [stderr] (Thread-125)     at io.netty.channel.DefaultChannelHandlerContext.invokeBind(DefaultChannelHandlerContext.java:463)
2016-09-05 10:36:13,197 ERROR [stderr] (Thread-125)     at io.netty.channel.DefaultChannelHandlerContext.bind(DefaultChannelHandlerContext.java:448)
2016-09-05 10:36:13,197 ERROR [stderr] (Thread-125)     at io.netty.channel.DefaultChannelPipeline.bind(DefaultChannelPipeline.java:842)
2016-09-05 10:36:13,197 ERROR [stderr] (Thread-125)     at io.netty.channel.AbstractChannel.bind(AbstractChannel.java:195)
2016-09-05 10:36:13,197 ERROR [stderr] (Thread-125)     at io.netty.bootstrap.AbstractBootstrap$2.run(AbstractBootstrap.java:338)
2016-09-05 10:36:13,198 ERROR [stderr] (Thread-125)     at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:370)
2016-09-05 10:36:13,198 ERROR [stderr] (Thread-125)     at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:353)
2016-09-05 10:36:13,198 ERROR [stderr] (Thread-125)     at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116)
2016-09-05 10:36:13,198 ERROR [stderr] (Thread-125)     at java.lang.Thread.run(Thread.java:745)

我看过 OpenShift 网络套接字指南 here ,表示应使用端口 8000。但我仍然收到错误。

在 Openshift 上,我在 WildFly Application Server 10 卡式盒上运行我的聊天服务器

感谢任何建议。

这是我的代码:

WebAppInitializer.java

    try {
        new Thread() {
            public void run() {
                com.jobs.spring.chat.Server chatServer = new com.jobs.spring.chat.Server();
                chatServer.startServer();
            }
        }.start();
    } catch (Exception e) {
        e.printStackTrace();
    }

服务器.java

import java.net.Socket;

import com.corundumstudio.socketio.AckRequest;
import com.corundumstudio.socketio.Configuration;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.listener.ConnectListener;
import com.corundumstudio.socketio.listener.DataListener;
import com.corundumstudio.socketio.listener.DisconnectListener;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * https://blog.openshift.com/paas-websockets/
 * @author Richard
 *
 */
public class Server {

    //private static final String SERVER = "localhost";
    private static final String SERVER = "jbosswildfly-easyjobs.rhcloud.com";
    private static final Integer PORT = 8000;

    public static void main(String[] args) {
        startServer();
    }

    public static void startServer() {
        Configuration config = new Configuration();
        config.setHostname(SERVER);
        config.setPort(PORT);
        final SocketIOServer server = new SocketIOServer(config);

        server.addConnectListener(new ConnectListener() {
            @Override
            public void onConnect(SocketIOClient client) {
                System.out.println("onConnected");
                client.sendEvent("chat_message:message", new Message("Welcome to the chat!"));
            }
        });

        server.addDisconnectListener(new DisconnectListener() {
            @Override
            public void onDisconnect(SocketIOClient client) {
                System.out.println("onDisconnected");
            }
        });

        server.addEventListener("chat_message:send", String.class, new DataListener<String>() {
            @Override
            public void onData(SocketIOClient client, String data, AckRequest ackSender) throws Exception {
                Message message = null;
                try {
                    message = new ObjectMapper().readValue(data.toString(), Message.class);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                message.setDate(System.currentTimeMillis());
                server.getBroadcastOperations().sendEvent("chat_message:message", message);
            }
        });

        System.out.println("Starting Chat server on " + SERVER + ":" + PORT+" ...");
        server.start();
        System.out.println("Chat server started");
        System.out.println("Chat server Environment Info: " + System.getenv());
        try {
            Socket socket = new Socket(SERVER, PORT);
            printSocketInformation(socket);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Prints debug output (to stdout) for the given Java Socket.
     */
    public static void printSocketInformation(Socket socket) {
        try {
            System.out.format("Port:                 %s\n", socket.getPort());
            System.out.format("Canonical Host Name:  %s\n", socket.getInetAddress().getCanonicalHostName());
            System.out.format("Host Address:         %s\n\n", socket.getInetAddress().getHostAddress());
            System.out.format("Local Address:        %s\n", socket.getLocalAddress());
            System.out.format("Local Port:           %s\n", socket.getLocalPort());
            System.out.format("Local Socket Address: %s\n\n", socket.getLocalSocketAddress());
            System.out.format("Receive Buffer Size:  %s\n", socket.getReceiveBufferSize());
            System.out.format("Send Buffer Size:     %s\n\n", socket.getSendBufferSize());
            System.out.format("Keep-Alive:           %s\n", socket.getKeepAlive());
            System.out.format("SO Timeout:           %s\n", socket.getSoTimeout());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

this link OpenShift 谈论端口绑定(bind)和代理。我真的不明白这一切。看起来我应该使用端口 8000(我就是),但我不清楚我应该使用什么主机名。我正在使用我的应用程序 url 名称 (jbosswildfly-easyjobs.rhcloud.com)。对吗?

如果我将地址更改为 http://jbosswildfly-easyjobs.rhcloud.com(即前缀 http://),我会收到以下错误:

java.net.SocketException: Unresolved address

enter image description here

最佳答案

我正在尝试找出解决方案。我有一些解决方案。所有人都建议将 -Djava.net.preferIPv4Stack=true 添加到 VM 选项。

Atlassian Documentation也得到了下面给出的根本原因和解决方案:

Cause

  1. This is one of the known issues with Java 7, as per this post.
  2. This can also be caused by any anti-virus or firewall software installed on the server.

Resolution

  1. Use the -Djava.net.preferIPv4Stack=true JVM system property to help enable support for IPv4 on Java 7.
  2. Check that anti-virus and firewall software on the server is not blocking Stash's ability to connect to the mail server.

此解决方案适用于 Java 7,但您使用的是 Java 8。所以我查找了您的堆栈跟踪。有一条线

 at io.netty.channel.socket.nio.NioServerSocketChannel.doBind(NioServerSocketChannel.java:125)

这表明您正在使用 netty

但是netty对版本有一定的要求。也有一些限制。

JDK 5 (Netty 3.x) or 6 (Netty 4.x) is enough. Some components such as HTTP/2 might have more requirements

Netty 4.x 的要求(link)

Java does not currently support ALPN or NPN (there is a tracking issue so go upvote it!). For lack of support in the JDK we need to use the Jetty-ALPN (or Jetty-NPN if on Java < 8) bootclasspath extension for OpenJDK. To do this, add a Xbootclasspath JVM option referencing the path to the Jetty alpn-boot jar.

java -Xbootclasspath/p:/path/to/jetty/alpn/extension.jar ...

Note that you must use the release of the Jetty-ALPN jar specific to the version of Java you are using.

JDK Ciphers

Java 7 does not support the cipher suites recommended by the HTTP2 RFC. To address this we suggest servers use Java 8 where possible or use an alternative JCE implementation such as Bouncy Castle. If this is not practical it is possible to use other ciphers but you need to ensure that the services you intend to call also support these ciphers forbidden by the HTTP/2 RFC and have evaluated the security risks of doing so.

Enabling ALPN or NPN

The SslContextBuilder has a setter for an ApplicationProtocolConfig which is used to configure ALPN or NPN. See the HTTP/2 examples for ALPN and SPDY examples for NPN usage.

详细说明可以通过this link .

建议:

所以检查你的netty版本并根据以上问题做出决定。或者尽可能使用 JDK 7。

关于java - 打开转换 java.net.SocketException : Permission denied,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39266277/

相关文章:

java - 如何在 build.gradle.kts 中设置变量

ios - 在 NSRunLoop 上调度流

linux - 使用 NFQUEUE 的 TCP 数据包处理

python - Bottle :全局变量 'request' 未定义

linux - 通过 Jenkins 运行时,OpenShift 上的 Gradle 构建失败

java - 将对象数组转换为字符串数组

java - StringUtils.isBlank 与正则表达式

JavaC CreateProcess error=206,文件名或扩展名太长

java - LDAP 和 JNDI 的 ServiceUnavailableException

apache-spark - Apache Spark 独立用于匿名 UID(无用户名)