2012-10-15 99 views
0

我刚开始学习java。我通过为客户端创建两个线程,接收用户输入的主线程以及用于接收服务器响应的inputThread,修改了服务器/客户端通信程序的客户端代码。我确信服务器已经将响应发送给客户端,但是,客户端没有获得响应消息。为什么客户端无法接收来自服务器的消息(java)

这是我的代码。任何人都可以帮我弄明白吗?谢谢

package clientnio; 

import java.net.*; 
import java.nio.*; 
import java.io.*; 
import java.nio.channels.*; 
import java.util.Scanner; 

public class ClientNIO { 
public static int bufferLen = 50; 
public static SocketChannel client; 
public static ByteBuffer writeBuffer; 
public static ByteBuffer readBuffer; 

public static void main(String[] args) { 
    writeBuffer = ByteBuffer.allocate(bufferLen); 
    readBuffer = ByteBuffer.allocate(bufferLen); 

    try { 
     SocketAddress address = new InetSocketAddress("localhost",5505); 
     System.out.println("Local address: "+ address); 
     client=SocketChannel.open(address); 
     client.configureBlocking(false); 

     //readBuffer.flip(); 
     new inputThread(readBuffer); 

     /* 
     String a="asdasdasdasddffasfas"; 
     writeBuffer.put(a.getBytes()); 
     writeBuffer.clear(); 
     int d=client.write(writeBuffer); 
     writeBuffer.flip(); 
     */ 

     while (true) { 
      InputStream inStream = System.in; 
      Scanner scan = new Scanner(inStream); 
      if (scan.hasNext()==true) { 
       String inputLine = scan.nextLine(); 
       writeBuffer.put(inputLine.getBytes()); 
       //writeBuffer.clear(); 
       System.out.println(writeBuffer.remaining()); 
       client.write(writeBuffer); 
       System.out.println("Sending data: "+new String(writeBuffer.array())); 
       writeBuffer.flip(); 
       Thread.sleep(300); 
      } 
     }     
    } 
    catch(Exception e) { 
     System.out.println(e); 
    } 

} 
} 

class inputThread extends Thread { 
private ByteBuffer readBuffer; 
public inputThread(ByteBuffer readBuffer1) { 
    System.out.println("Receiving thread starts."); 
    this.readBuffer = readBuffer1; 
    start(); 
} 

@Override 
public void run() { 
    try { 
     while (true) { 
      readBuffer.flip(); 
      int i=ClientNIO.client.read(readBuffer); 
      if(i>0) { 
       byte[] b=readBuffer.array(); 
       System.out.println("Receiving data: "+new String(b)); 
        //client.close(); 
        //System.out.println("Connection closed."); 
        //break; 
      } 
      Thread.sleep(100); 
     } 
    } 
    catch (Exception e) { 
     System.out.println(e); 
    } 
    } 
} 
+0

我很困惑。它看起来像你显示服务器代码..但我没有看到你的客户端代码? – Austin

+1

最可能的解释是您的服务器和客户端不实现相同的协议。例如,如果您的客户希望应用程序级消息以换行符终止,则服务器必须以换行符终止发送它们。 –

+0

@奥斯汀:显示的可能是客户端代码。否则,它会使用'ServerSocketChannel'。 – rwong

回答

-1

声明:我不是Java的活跃用户。 (我只在学校使用它。)


忠告:我觉得如果你使用阻塞模式这将大大简化了调试过程中,至少要等到你的代码示例工作正常。 (目前您的代码似乎并没有从非阻塞模式中受益。)


我已经确定了两个问题,最终进入的代码四个可能的线,可能需要改变:

  1. ByteBuffer分配它的后备数组,它通过将position设置为0并将limit设置为该数组的容量来设置自己准备写入。你的两个用途ByteBuffer.flip()(分别在书写循环和阅读循环中)似乎与公约相违背。
  2. 调用ByteBuffer.array()方法总是返回整个支持数组,因此它的大小始终为bufferLen。因此,从全尺寸阵列构建的String可能包含来自先前传输的垃圾。
    • 典型地,该阵列需要被修整,以传输大小,以及String和之间的转换的字节数组必须使用相同的编码作为服务器。

我建议对第一个问题的变化:
(注:我不知道如何解决的阵列微调和编码问题)

writeBuffer.put(inputLine.getBytes()); 
writeBuffer.flip();      // <--here 
client.write(writeBuffer); 
... 
writeBuffer.clear();      // <-- should be clear() instead of flip() 
Thread.sleep(300); 

// readBuffer.flip();      // <-- remove this line 
int i=ClientNIO.client.read(readBuffer); 
if(i>0) { 
    readBuffer.flip();      // <-- move it here 
    byte[] b=readBuffer.array(); 
    System.out.println("Receiving data: "+new String(b)); 
    ... 
} 

阅读个

参考

+0

嗨,感谢您的帮助。我检查了服务器端,它确实收到了客户端发送的预期数据。我也试过你的建议,但结果是一样的。我正在考虑是否这是两个线程使用相同的套接字竞争造成的。 – user1745931

+0

非常感谢。我按照你的建议更正了代码。现在客户端可以从服务器获得响应。 :P – user1745931

1

调用上的缓冲flip()之前,这是错误的。不要这样做。您需要在写入+之前将其翻转或从中取出,然后再将其翻转compact()

相关问题