我遇到了多人游戏的问题。现在,我只是想让服务器将当前级别发送给客户端。服务器肯定是在发送数据,但它永远不会到达客户端应用程序。
客户代码:
public void run() {
while(true)
{
try {
sel.select();
Set readyKeys = sel.selectedKeys();
Iterator itr = readyKeys.iterator();
while(itr.hasNext())
{
SelectionKey key = (SelectionKey) itr.next();
itr.remove();
SocketChannel ch = (SocketChannel) key.channel();
if(key.isReadable())
{
inputbuf.clear();
long bytesRead = ch.read(inputbuf);
inputbuf.flip();
byte[] test = inputbuf.array();
{
for(int i=0; i < inputbuf.remaining(); i++)
{
System.out.print(test[i]+" ");
}
}
byte cmd = 0;
cmd = inputbuf.get();
switch(cmd)
{
case 1:
//do something
case 2:
//do something else
break;
}
}
else if(key.isConnectable())
{
sc.finishConnect();
sc.register(sel, SelectionKey.OP_READ);
}
}
} catch (IOException ex) {
Buildsim.error("Error handling input from server", ex);
}
}
}
服务器代码:
public RemotePlayer(SocketChannel s)
{
sc = s;
try {
sel = Selector.open();
sc.configureBlocking(false);
sc.register(sel, SelectionKey.OP_WRITE);
socket = sc.socket();
ip = socket.getInetAddress().toString();
System.out.println("New connection from "+ip);
inputbuf = ByteBuffer.allocate(1048576);
outputbuf = ByteBuffer.allocate(1048576);
inputbuf.clear();
outputbuf.clear();
}
catch(Exception e)
{
Buildsim.error("Connection error: ", e);
}
sendLevel();
}
public void sendObject(GameObject obj)
{
//Sends a packet of the object, then does the same for the object's children
}
public void sendLevel()
{
try {
outputbuf.put((byte) 0x01);
outputbuf.flip();
sc.write(outputbuf);
sendObject(Buildsim.w.parts.get(0)); //root object
}
catch(IOException e)
{
Buildsim.error("Error sending level to "+ip, e);
}
}
唯一能够到达客户端的是字节0x01(表示电平变化)。
提前致谢。
答案 0 :(得分:0)
根据您提供给我们的信息量,我们只能提供全局提示,例如:您是否确保套接字流未被缓冲,并且在信息写入后您flush()
?
数据可能在等待填充的缓冲区中等待发送。
修改强>
您将SocketChannel设置为非阻塞模式,因此您可以假设在发送方负责刷新,我假设客户端不缓冲其输入?
问题可能是SocketChannel.write()没有被编写整个缓冲区,但可能会提前返回。您需要在while循环中包装写入以跟踪写入的字节,以确保您的数据实际写入通道。引用Javadoc:
除非另有说明,否则写一下 操作将在之后返回 写入所有r请求的字节。 某些类型的频道,具体取决于 他们的状态,可能只写一些 字节或可能根本没有。 :一种 非阻塞模式的套接字通道, 例如,不能再写了 字节数比套接字中的空闲字节数多 输出缓冲区。