Java 进程能否连接到自己创建的套接字?

Java 进程能否连接到自己创建的套接字?,java,Java,编辑:下面的代码没有抛出异常,但没有输出和挂起。它应该输出“测试消息”。在main()中,我们启动一个线程,该线程给定一个服务器套接字侦听随机端口。主线程尝试连接同一随机端口上的ServerSocket并与之通信,但显然失败了。为什么? public class IntraProcSockTest { private static int port; private class Listener extends Thread { public Listener() { }

编辑:下面的代码没有抛出异常,但没有输出和挂起。它应该输出“测试消息”。在main()中,我们启动一个线程,该线程给定一个服务器套接字侦听随机端口。主线程尝试连接同一随机端口上的ServerSocket并与之通信,但显然失败了。为什么?

public class IntraProcSockTest {
private static int port;

private class Listener extends Thread {
    public Listener() {
    }

    public void run() {
        try {
            ServerSocket serverSocket = new ServerSocket(0);
            port = serverSocket.getLocalPort();
            Socket socket = serverSocket.accept();

            BufferedReader in;
            String fromClient;

            in = new BufferedReader(new InputStreamReader(
                    socket.getInputStream()));

            while ((fromClient = in.readLine()) != null) {
                System.out.println("From client: " + fromClient);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public IntraProcSockTest() {
    new Listener().start();
}

public static void main(String[] args) {
    new IntraProcSockTest();

    try {
        Thread.sleep(5000);
        Socket socket = new Socket("localhost", port);
        PrintWriter socketOut = new PrintWriter(socket.getOutputStream());

        socketOut.println("Test message");
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

进程可以连接到自己创建的套接字,没有问题显示引发异常的代码和/或有关异常的更多详细信息

首先,请小心不要为客户端套接字指定一个本地端口(一个连接到另一个正在侦听的端口)。让操作系统选择一个随机端口。请记住,任何套接字都由四个元素标识(远程主机、本地主机、远程端口、本地端口),如果将服务器套接字和客户端套接字绑定到同一个本地端口上,则将其设为
4498
,两个套接字的定义如下:
(本地主机、本地主机、4498、4498)
但这不起作用。我怀疑这可能是你的问题。
为了避免此类问题,客户端套接字通常绑定到由操作系统选择的随机端口。向我们展示您的代码,特别是创建客户端套接字并连接到服务器套接字的部分


关于IPC,使用套接字作为进程间甚至进程内通信技术并不总是不好的。显然,性能更差,您可能会失去一些代码可读性,但您的软件将很容易移植到网络(分布式)应用程序。这取决于您的计划,它不像IPC套接字==坏。

进程可以连接到自己创建的套接字,没有问题显示引发异常的代码和/或有关异常的更多详细信息

首先,请小心不要为客户端套接字指定一个本地端口(一个连接到另一个正在侦听的端口)。让操作系统选择一个随机端口。请记住,任何套接字都由四个元素标识(远程主机、本地主机、远程端口、本地端口),如果将服务器套接字和客户端套接字绑定到同一个本地端口上,则将其设为
4498
,两个套接字的定义如下:
(本地主机、本地主机、4498、4498)
但这不起作用。我怀疑这可能是你的问题。
为了避免此类问题,客户端套接字通常绑定到由操作系统选择的随机端口。向我们展示您的代码,特别是创建客户端套接字并连接到服务器套接字的部分


关于IPC,使用套接字作为进程间甚至进程内通信技术并不总是不好的。显然,性能更差,您可能会失去一些代码可读性,但您的软件将很容易移植到网络(分布式)应用程序。这取决于您的计划,它不像IPC套接字==坏。

要在一个线程中创建套接字连接,您可以

ServerSocket ss = new ServerSocket(0); // open a random free port.
Socket c = new Socket(ss.getInetAddress(), ss.getLocalPort());
Socket s = ss.accept();
ss.close();

final byte[] bytes = "Hello World!".getBytes();
final OutputStream out = c.getOutputStream();
out.write(bytes.length);
out.write(bytes);


final DataInputStream in = new DataInputStream(s.getInputStream());
int len = in.read();
final byte[] b = new byte[len];
in.readFully(b);
System.out.println(new String(b));

c.close();
s.close();

如果您只需要进程内的IPC,那么套接字并不是最快或最简单的方法。尝试使用管道(NIO)或管道输入/输出流(IO)。它更快更简单

Pipe pipe = Pipe.open();
SinkChannel sink = pipe.sink();
SourceChannel source = pipe.source();

顺便说一句:但是,您可以在同一线程中连接客户端和服务器套接字

使用交换机的速度快10倍,而使用环形缓冲区的速度又快了一倍


如果您想要方便,使用ExecutorService是将工作删除到后台线程池的最佳方式。这仍然可以每秒执行数百万个任务。

要在一个线程中创建套接字连接,您可以

ServerSocket ss = new ServerSocket(0); // open a random free port.
Socket c = new Socket(ss.getInetAddress(), ss.getLocalPort());
Socket s = ss.accept();
ss.close();

final byte[] bytes = "Hello World!".getBytes();
final OutputStream out = c.getOutputStream();
out.write(bytes.length);
out.write(bytes);


final DataInputStream in = new DataInputStream(s.getInputStream());
int len = in.read();
final byte[] b = new byte[len];
in.readFully(b);
System.out.println(new String(b));

c.close();
s.close();

如果您只需要进程内的IPC,那么套接字并不是最快或最简单的方法。尝试使用管道(NIO)或管道输入/输出流(IO)。它更快更简单

Pipe pipe = Pipe.open();
SinkChannel sink = pipe.sink();
SourceChannel source = pipe.source();

顺便说一句:但是,您可以在同一线程中连接客户端和服务器套接字

使用交换机的速度快10倍,而使用环形缓冲区的速度又快了一倍


如果您想要方便,使用ExecutorService是将工作删除到后台线程池的最佳方式。这仍然可以每秒执行数百万个任务。

请参见此。解决:我必须刷新套接字:忘记使用自动刷新请参见此。解决:我必须刷新套接字:忘记使用自动刷新。第二段确实是我的问题。因此,在本地主机的同一端口上绑定客户端和服务器套接字对我来说不起作用。当然,但这绝对不是问题,因为您可以让O.S.将套接字绑定到它可以找到的任何可用本地端口。只需确保指定远程端口,否则也无法连接。本地端口和远程端口之间的区别总是有点混淆。对于服务器套接字,本地端口很重要,对于客户端套接字,只关心远程端口。关于随机端口的问题:当服务器选择一个随机端口时,客户端如何知道要连接到它所在套接字的端口?好的,事实上,没有服务器套接字绑定到随机本地端口。对于服务器套接字来说,本地端口很重要,对于客户端套接字来说,只关心远程端口,本地端口是随机的。作为一个例外,在IPC套接字中,服务器也经常使用随机端口。但我不想让您感到困惑:我发现如果您修复代码,它会更有用。:)啊第二段确实是我的问题。因此,在本地主机的同一端口上绑定客户端和服务器套接字对我来说不起作用。当然,但这绝对不是问题,因为您可以让O.S.将套接字绑定到它可以找到的任何可用本地端口。只需确保指定远程端口,否则也无法连接。本地端口和远程端口之间的区别总是有点混淆。对于服务器套接字,本地端口很重要,对于客户端套接字,只关心远程端口