编辑:下面的代码不会抛出任何异常,但没有输出并挂起。它应输出“测试信息”。在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();
}
}
答案 0 :(得分:3)
进程可以连接到自己创建的套接字,没有问题。 向我们展示引发异常的代码和/或有关异常的更多详细信息。
首先,请注意不为客户端套接字指定本地端口(连接到另一个正在侦听的端口)。让操作系统选择一个随机端口。请记住,任何套接字都由四个元素(remote host, local host, remote port, local port)
标识,如果您在同一个本地端口上绑定服务器套接字和客户端套接字,则将其设为4498
,两个套接字定义如下:(localhost, localhost, 4498, 4498)
这不起作用。我怀疑这可能是你的问题
为避免此类问题,客户端套接字通常绑定到OS选择的随机端口。向我们展示您的代码,特别是创建客户端套接字并连接到服务器套接字的部分。
关于IPC,使用套接字作为进程间甚至进程内通信技术并不总是不好。显然,性能更差,并且您可能会丢失一些代码可读性,但您的软件可以轻松移植到网络(分布式)应用程序。这取决于你的计划,它不像IPC套接字==坏。
答案 1 :(得分:2)
要在一个线程中创建一个Socket连接,你可以。
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,套接字不是最快或最简单的方法。尝试使用Pipe(NIO)或PipeInput / OutputStream(IO)。它更快更简单。
Pipe pipe = Pipe.open();
SinkChannel sink = pipe.sink();
SourceChannel source = pipe.source();
或
PipedOutputStream output = new PipedOutputStream();
PipedInputStream input = new PipedOutputStream(output);
BTW:您可以在同一个线程中连接客户端和服务器Socket,但
使用交换机的速度提高了10倍,使用环形缓冲区的速度再快了。
如果您想要方便,使用ExecutorService是将工作删除到后台线程池的最佳方法。这仍然可以每秒执行数百万个任务。