我调整了这个代码How to send and receive serialized object in socket channel,我的实时模拟用来发送对象,但是我遇到了一个又一个的异常,这是因为这种代码阻塞在本质上是如何用javanio将代码转换为非阻塞的。
/*
* Writer
*/
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.InetSocketAddress;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
public class CleanSender implements Runnable {
private SimManager SM;
private BallState ballState = new BallState(10, 5);
private ServerSocketChannel ssChannel;
private Thread tRunSer = new Thread(this, "ServerSelectThread");
public static void main(String[] args) throws IOException {
CleanSender server = new CleanSender();
server.startServer();
}
private void startServer() throws IOException {
ssChannel = ServerSocketChannel.open();
ssChannel.configureBlocking(true);
int port = 2345;
ssChannel.socket().bind(new InetSocketAddress(port));
// SM = new SimManager(this, BS);
// SM.start(); // GameEngine thread starting here
tRunSer.start();
}
public void run() {
try {
SocketChannel sChannel = ssChannel.accept();
while (true) {
ObjectOutputStream oos = new ObjectOutputStream(sChannel
.socket().getOutputStream());
oos.writeObject(ballState);
System.out.println("Sending String is: '" + ballState.X + "'" + ballState.Y);
oos.close();
System.out.println("Sender Start");
System.out.println("Connection ended");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}Client:它一直在寻找服务器的回复。
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.InetSocketAddress;
import java.nio.channels.SocketChannel;
public class CleanReceiver implements Runnable {
private SocketChannel sChannel;
private Thread receiverThread = new Thread(this, "receiverThread");
private synchronized void startServer() throws IOException {
sChannel = SocketChannel.open();
sChannel.configureBlocking(true);
if (sChannel.connect(new InetSocketAddress("localhost", 2345))) {
receiverThread.start();
}
}
public void run() {
while (true) {
try {
ObjectInputStream ois = new ObjectInputStream(sChannel.socket()
.getInputStream());
BallState s = (BallState) ois.readObject();
System.out.println("String is: '" + s.X + "'" + s.Y);
ois.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("End Receiver");
}
}
public static void main(String[] args)
throws IOException, ClassNotFoundException {
CleanReceiver rc=new CleanReceiver();
rc.startServer();
System.out.println("End Receiver");
}
}当服务器必须保持连接客户端并同时将模拟状态发送到已经连接的客户端时,会在这种情况下工作吗?,我正在寻找专家的目光。
谢谢,
吉比拉
发布于 2011-03-28 14:30:37
您的代码有两个主要问题:
close(),在发送端使用flush()而不是close()来确保缓冲区被刷新。在实现阻塞IO时,如果每个客户端都有一个线程是不可接受的,您可以以非阻塞的方式实现服务器,但是,正如Peter已经说过的那样,它更复杂,所以我建议您首先让它使用阻塞IO。
发布于 2011-03-28 13:47:16
如果您正在使用ObjectInputStream或ObjectOutputStream,我建议您继续使用阻塞IO。在这些库中使用非阻塞IO是实际收益的10倍。
您是否考虑过使用ServerSocket和Socket而不是NIO。这些将更容易使用,而对象流的来源都是设计用来使用的,
https://stackoverflow.com/questions/5459750
复制相似问题