我需要在 LAN 中不同设备上的两个程序之间建立管道连接。即,我的 LAN 中的设备 A 应连接到设备 B:portX。问题是我无法将它们直接连接起来。我要做的就是让设备 A 连接到服务器,然后让该服务器连接到设备 B。在我的服务器上,我监听端口“portX”,当我获得连接时,我连接到设备 B相同的端口。然后我必须通过服务器将数据从 A 传输到 B,但由于某种原因,设备 B 在从 A 接收到数据(命令)时没有执行其应该执行的操作。
我该怎么做?
这是我一直在尝试执行此操作的方法:
public class Main {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(8000);
} catch (IOException e) {
System.err.println("Could not listen on port: 8000.");
System.exit(1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
System.err.println("connection accepted");
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}
Socket remoteSocket = null;
try {
remoteSocket = new Socket("192.168.1.74", 8000);
} catch (Exception e) {
System.out.println("Failed to connect to device B");
}
PrintWriter remoteOut = new PrintWriter(remoteSocket.getOutputStream(),
true);
BufferedReader remoteIn = new BufferedReader(new InputStreamReader(
remoteSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
String inputLine;
System.out.println("Hi, we are before the while");
int inputChar = 0;
while ((inputChar = in.read()) >= 0) {
remoteOut.println(inputChar);
System.out.println(inputChar);
}
System.out.println("We are after the while");
out.close();
in.close();
remoteIn.close();
remoteOut.close();
clientSocket.close();
serverSocket.close();
remoteSocket.close();
}
}
提前致谢, 蒂莫菲
最佳答案
我创建了一个使用 NIO channel 的版本。这种方法的好处是您可以使用单个线程来管理来自多个源的内容。我不一定需要知道两个服务之间的协议(protocol)是什么,因为我们只是复制字节。如果您只想使用普通的旧套接字,则需要使用互斥体和 2 个线程在两个套接字之间读取/写入数据(套接字不是线程安全的)。
注意:处理错误情况可能有比仅删除连接并创建新连接更好的方法。
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Set;
/**
* Socket Gateway for SO Question 7528528
* User: jhawk28
* Date: 9/26/11
* Time: 9:03 PM
* <p/>
* http://stackoverflow.com/questions/7528528/java-ports-sockets-piping-a-connection-through-a-programme
*/
public class Gateway
{
public static void main(String[] args) throws IOException
{
// Set up Server Socket and bind to the port 8000
ServerSocketChannel server = ServerSocketChannel.open();
SocketAddress endpoint = new InetSocketAddress(8000);
server.socket().bind(endpoint);
server.configureBlocking(false);
// Set up selector so we can run with a single thread but multiplex between 2 channels
Selector selector = Selector.open();
server.register(selector, SelectionKey.OP_ACCEPT);
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (true)
{
// block until data comes in
selector.select();
Set<SelectionKey> keys = selector.selectedKeys();
for (SelectionKey key : keys)
{
if (!key.isValid())
{
// not valid or writable so skip
continue;
}
if (key.isAcceptable())
{
// Accept socket channel for client connection
ServerSocketChannel channel = (ServerSocketChannel) key.channel();
SocketChannel accept = channel.accept();
setupConnection(selector, accept);
}
else if (key.isReadable())
{
try
{
// Read into the buffer from the socket and then write the buffer into the attached socket.
SocketChannel recv = (SocketChannel) key.channel();
SocketChannel send = (SocketChannel) key.attachment();
recv.read(buffer);
buffer.flip();
send.write(buffer);
buffer.rewind();
} catch (IOException e)
{
e.printStackTrace();
// Close sockets
if (key.channel() != null)
key.channel().close();
if (key.attachment() != null)
((SocketChannel) key.attachment()).close();
}
}
}
// Clear keys for next select
keys.clear();
}
}
public static void setupConnection(Selector selector, SocketChannel client) throws IOException
{
// Connect to the remote server
SocketAddress address = new InetSocketAddress("192.168.1.74", 8000);
SocketChannel remote = SocketChannel.open(address);
// Make sockets non-blocking (should be better performance)
client.configureBlocking(false);
remote.configureBlocking(false);
client.register(selector, SelectionKey.OP_READ, remote);
remote.register(selector, SelectionKey.OP_READ, client);
}
}
关于Java、端口、套接字、通过程序管道连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7528528/