我是docker的新手,需要使用java套接字从正在运行的centos docker容器内部连接到运行容器的主机。当尝试连接SocketException时发生:
[root@743fedf46128 test]# java SocketTest 10.1.196.134 4444 127.0.0.1 0
Trying to connect using ip address
Using remote ip 10.1.196.134
Using remote port 4444
Using local ip 127.0.0.1
Using local port 0
/10.1.196.134, 4444, /127.0.0.1, 0
java.net.SocketException: Invalid argument or cannot assign requested address
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:579)
at java.net.Socket.connect(Socket.java:528)
at SocketTest.main(SocketTest.java:54)
Java Class TestSocket实际上只是尝试打开套接字:
public static void main(String[] args) {
String remoteIp = args[0];
String remotePort = args[1];
String localIp = args[2];
String localPort = args[3];
System.out.println("Trying to connect using ip address");
System.out.println("Using remote ip " + remoteIp);
System.out.println("Using remote port " + remotePort);
System.out.println("Using local ip " + localIp);
System.out.println("Using local port " + localPort);
Socket workSocket = null;
try {
InetAddress remoteAddress = InetAddress.getByName(remoteIp);
InetAddress localAddress = InetAddress.getByName(localIp);
int rPort = Integer.parseInt(remotePort);
int lPort = Integer.parseInt(localPort);
System.out.println(remoteAddress + ", " + rPort + ", " + localAddress + ", " + lPort);
workSocket = new Socket();
workSocket.setReuseAddress(true);
workSocket.bind(new InetSocketAddress(localAddress, lPort));
workSocket.setSoTimeout(1000);
workSocket.connect(new InetSocketAddress(remoteAddress, rPort));
}
它在最后一行(连接)失败。
Ping以及从正在运行的容器中telnet端口但是工作:
[admin@pluto ~]$ docker exec -it --user root pensive_almeida bash
[root@743fedf46128 test]# ping -c 3 10.1.196.134
PING 10.1.196.134 (10.1.196.134) 56(84) bytes of data.
64 bytes from 10.1.196.134: icmp_seq=1 ttl=64 time=0.047 ms
64 bytes from 10.1.196.134: icmp_seq=2 ttl=64 time=0.101 ms
64 bytes from 10.1.196.134: icmp_seq=3 ttl=64 time=0.099 ms
--- 10.1.196.134 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.047/0.082/0.101/0.026 ms
[root@743fedf46128 test]# telnet 10.1.196.134 4444
Trying 10.1.196.134...
Connected to 10.1.196.134.
Escape character is '^]'.
This is a test
Connection closed by foreign host.
任何人都可以提供一个提示,为什么尝试连接失败与java? 为了完整性,我的Dockerfile看起来像这样:
FROM centos:centos7
# Set the proxies
ENV HTTP_PROXY 'http://175.23.236.88:3128/'
ENV HTTPS_PROXY 'http://175.23.236.88:3128/'
# Install telnet
RUN yum -y install telnet
RUN yum -y install wget
# Prepare environment
ENV JAVA_HOME /opt/java
ENV PATH $PATH:$JAVA_HOME/bin
# Install Oracle Java7
RUN wget --no-check-certificate --no-cookies --header "Cookie:oraclelicense=accept-securebackup-cookie" \
http://download.oracle.com/otn-pub/java/jdk/7u80-b15/jdk-7u80-linux-x64.tar.gz && \
tar -xvf jdk-7u80-linux-x64.tar.gz && \
rm jdk*.tar.gz && \
mv jdk* ${JAVA_HOME}
WORKDIR /opt/test
# Add the test class
ADD dockerfiles/SocketTest.class /opt/test/SocketTest.class
提前感谢您的回复。
答案 0 :(得分:0)
您可以将--net = host添加到docker run命令,但这样主机就可以完全访问您的容器。但是,您可以在Dockerfile中或docker run命令中的外部公开端口,但我更喜欢前者。
以下是我的一个例子:
Pull base image
FROM ubuntu:14.04
RUN apt-get update
RUN apt-get install software-properties-common -y
RUN add-apt-repository ppa:webupd8team/java -y
RUN apt-get update
RUN echo debconf shared/accepted-oracle-license-v1-1 select true | debconf-set-selections
RUN apt-get install oracle-java8-installer -y
RUN apt-get install oracle-java8-set-default -y
RUN mkdir /temporary
ADD Client.jar /temporary
WORKDIR /temporary
EXPOSE 15000
ENTRYPOINT /bin/bash
答案 1 :(得分:0)
您必须找到docker0网络接口inetAddress才能到达主机。尝试运行ifconfig并检查docker0的inetAddr。通常它是 172.17.0.1 ,但它可能会因您运行的docker版本而异。这应该足以与主机通信。