Java、端口、插座、管道通过程序连接
我需要在局域网中不同设备上的两个程序之间建立管道连接。也就是说,我的LAN中有一个设备A应该连接到设备B:portX。问题是我无法将它们直接连接起来。我要做的是让设备A连接到服务器,并让服务器连接到设备B。在我的服务器上,我监听端口“portX”,当我获得连接时,我在同一端口上连接到设备B。然后我必须通过服务器将数据从A传输到B,但由于某些原因,设备B在从A接收数据(命令)时没有执行它应该执行的操作 我该怎么做 以下是我一直试图做到这一点的方式:Java、端口、插座、管道通过程序连接,java,sockets,port,Java,Sockets,Port,我需要在局域网中不同设备上的两个程序之间建立管道连接。也就是说,我的LAN中有一个设备A应该连接到设备B:portX。问题是我无法将它们直接连接起来。我要做的是让设备A连接到服务器,并让服务器连接到设备B。在我的服务器上,我监听端口“portX”,当我获得连接时,我在同一端口上连接到设备B。然后我必须通过服务器将数据从A传输到B,但由于某些原因,设备B在从A接收数据(命令)时没有执行它应该执行的操作 我该怎么做 以下是我一直试图做到这一点的方式: 公共班机{ 公共静态void main(字符串
公共班机{
公共静态void main(字符串[]args)引发IOException{
ServerSocket ServerSocket=null;
试一试{
serverSocket=新的serverSocket(8000);
}捕获(IOE异常){
System.err.println(“无法侦听端口:8000”);
系统出口(1);
}
套接字clientSocket=null;
试一试{
clientSocket=serverSocket.accept();
System.err.println(“已接受连接”);
}捕获(IOE异常){
System.err.println(“接受失败”);
系统出口(1);
}
套接字remoteSocket=null;
试一试{
remoteSocket=新套接字(“192.168.1.74”,8000);
}捕获(例外e){
System.out.println(“未能连接到设备B”);
}
PrintWriter remoteOut=新的PrintWriter(remoteSocket.getOutputStream(),
正确的);
BufferedReader remoteIn=新的BufferedReader(新的InputStreamReader(
remoteSocket.getInputStream());
PrintWriter out=新的PrintWriter(clientSocket.getOutputStream(),true);
BufferedReader in=新的BufferedReader(新的InputStreamReader(
getInputStream());
字符串输入线;
System.out.println(“嗨,我们在这之前”);
int inputChar=0;
而((inputChar=in.read())>=0){
println(inputChar);
System.out.println(inputChar);
}
System.out.println(“我们在找时间”);
out.close();
in.close();
remoteIn.close();
remoteOut.close();
clientSocket.close();
serverSocket.close();
remoteSocket.close();
}
}
提前感谢,,
蒂莫菲您的问题是,您正在使用PrintWriter作为转发机制。你读入一个字符,然后写出字符+换行符。尝试将其切换到
remoteOut.print(inputChar)代码>
更好的解决方案是读取字符,然后写出字符(可以使用BufferedWriter)。commons io已经有了拷贝方法,可以在中执行这类操作。我创建了一个使用NIO通道的版本。这种方法的好处是,您可以使用单个线程来管理来自多个源的内容。我不需要知道两个服务之间的协议是什么,因为我们只是复制字节。如果只想使用普通的旧套接字,则需要使用互斥锁和两个线程来读/写两个套接字之间的数据(套接字不是线程安全的)
注意:可能有更好的方法来处理错误情况,而不仅仅是删除连接并创建新连接
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);
}
}
import java.io.IOException;
导入java.net.InetSocketAddress;
导入java.net.SocketAddress;
导入java.nio.ByteBuffer;
导入java.nio.channels.*;
导入java.util.Set;
/**
*SO问题7528528的套接字网关
*用户:jhawk28
*日期:2011年9月26日
*时间:晚上九时零三分
*
* http://stackoverflow.com/questions/7528528/java-ports-sockets-piping-a-connection-through-a-programme
*/
公共类网关
{
公共静态void main(字符串[]args)引发IOException
{
//设置服务器套接字并绑定到端口8000
ServerSocketChannel服务器=ServerSocketChannel.open();
SocketAddress端点=新的InetSocketAddress(8000);
server.socket().bind(端点);
server.configureBlocking(false);
//设置选择器,以便我们可以使用单个线程运行,但在两个通道之间进行多路传输
选择器=选择器。打开();
服务器注册(选择器,SelectionKey.OP_ACCEPT);
ByteBuffer缓冲区=ByteBuffer.allocate(1024);
while(true)
{
//阻止,直到数据进入
selector.select();
设置键=选择器。selectedKeys();
用于(选择按键:按键)
{
如果(!key.isValid())
{
//无效或不可写,请跳过
继续;
}
if(key.isAcceptable())
{
//接受客户端连接的套接字通道
ServerSocketChannel=(ServerSocketChannel)key.channel();
SocketChannel accept=channel.accept();
设置连接(选择器,接受);
}
else if(key.isReadable())
{
尝试
{
//从套接字读入缓冲区,然后将缓冲区写入连接的套接字。
SocketChannel recv=(SocketChannel)key.channel();
SocketChannel send=(SocketChannel)key.attachment();
记录读取(缓冲区);
flip();
发送、写入(缓冲区);
buffer.rewind();
}捕获(IOE异常)
{
e、 printStackTrace();
//闭合插座
if(key.channel()!=null)
key.channel().close();
if(key.attachment()!=null)
((SocketChannel)key.attachment()).close();
}
}
}
//清除下一选择的关键点
键。清除();
}
}
公共静态void setupConnection(选择器、SocketChannel客户端)引发IOException
{
//连接到远程服务器
短袜
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);
}
}