2015-01-09 5 views
2

Hy,Чтение строки из гнезда канала

У меня есть следующий код:

public AppThread(SocketChannel socketChannel){ 
    this.socketChannel=socketChannel; 
    } 

     public void run(){ 
      try{ 
       ByteBuffer bb = ByteBuffer.allocate(11);  
       socketChannel.read(bb); 
       //byte[] b = new byte[bb.capacity()]; 
      // bb.get(b, 0, 11); 
       System.out.println(bb.toString()); 
       byte[] a = new byte[11]; 
       CharBuffer cb = bb.asCharBuffer(); 
       System.out.println(cb); 
       bb.get(a); 

       App app=new App(); 
      // String an = new String(b); 
       //String zodie = Zodie.getZodie(an); 
       //b = new byte[zodie.length()]; 
       //b = zodie.getBytes(); 
       bb.clear(); 
       //bb.put(b); 
       socketChannel.write(bb); 
       socketChannel.close(); 
      } 
      catch(IOException e){ 
       System.err.println("Server comunication error : "+e.getMessage()); 
      } 
      } 
} 

и zodie статического метод, который получает строку и возвращает строку.

Как я могу получить строку, записанную в SocketChannel, чтобы передать ее в качестве аргумента для статического метода зодиака.

Я упоминаю, что на стороне клиента я посылаю массив байтов, и я проверил, и все в порядке.

стороне клиента:

byte[] a = an.getBytes(); 
     System.out.println(new String(a)); 
    ByteBuffer bb=ByteBuffer.allocate(11); 
    // Varianta 1 
    bb.put(a); 
    // Varianta 2 
    // LongBuffer lb=bb.asLongBuffer(); 
    // lb.put(0,m).put(1,n); 
    try{ 
     sc.write(bb); 
     bb.clear(); 
     sc.read(bb); 
     // Varianta 1 
     //a = new byte[bb.remaining()]; 
     zodie=bb.toString(); 
     // Varianta 2 
     // r=lb.get(0); 
     System.out.println("Zodia : "+ zodie); 
     sc.close(); 

С уважением,

я получаю ошибку сервера:

Server ready... 
    java.nio.HeapByteBuffer[pos=1 lim=11 cap=11] 

    Exception in thread "pool-1-thread-1" java.nio.BufferUnderflowException 
     at java.nio.HeapByteBuffer.get(Unknown Source) 
     at java.nio.ByteBuffer.get(Unknown Source) 
     at server.AppThread.run(AppThread.java:27) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
     at java.lang.Thread.run(Unknown Source) 

ответ

1

Вопрос был на стороне клиента. Я использовал CharBuffer как wraper

Scanner scanner=new Scanner(System.in); 
String m; 
System.out.println("Enter the date (yyyy-mm-dd) :"); 
m=scanner.next()+" "; 

CharBuffer c = CharBuffer.wrap(m); 
System.out.println("Sending date ...: " + c); 
ByteBuffer b = Charset.forName("ISO-8859-1").encode(c); 
b.compact(); 
System.out.println("Bytebuffer has the capacity of "+ 
b.capacity() + "pointer position on bytebuffer is on: "+ b.position() + " and the limit is:" + b.limit()); 
b.flip(); 

На стороне сервера:

CharBuffer c; 
    ByteBuffer bb = ByteBuffer.allocate(11);  
    System.out.println("Server allocated a number of 11 octets to ByteBuffer"); 

    socketChannel.read(bb); 
    bb.flip();//sets the Position to 0 and limit to the number of bytes to be read. 
    CharBuffer c = Charset.forName("ISO-8859-1").decode(bb); 
      System.out.println("Got " + c); 

    byte[] byteArray = new byte[11]; 
    bb.get(byteArray); 
    System.out.println("Server got from client the string: " +new String(byteArray)); 
    String an = new String(byteArray); 
    bb.clear(); 
-1

Вы проблема заключается в линии bb.get (а);

Вы задаете 11 символов массива в качестве параметра и, таким образом, метод GET() ожидает, что бб содержит 11 символов, но он содержит только 1.

Причина заключается в том, что когда вы пишете 11 символов в сокет они не гарантируется чтобы прибыть все сразу. Они могут прибывать в небольшие группы, такие как 1 и 10 или 5 и 6 и т. Д.

Вам нужно посмотреть и прочитать из сокета и проверить результат вызова read(). Что-то в строках:

for (;;) { 
    int numberOfBytesRead =socket.read(buf); 
    if (numberOfBytesRead < 0) { break; } 
} 
+0

Я вставленной следующую строку для (;;) { \t \t \t System.out.println ("ххх @@@ "); \t \t \t int numberOfBytesRead = socketChannel.read (bb); \t \t \t System.out.println (numberOfBytesRead); \t \t \t if (numberOfBytesRead <0) {break; } \t \t \t} но на выходе я получаю только одно: «xxx @@@». Контур не должен прерываться и не увеличиваться. :-( – SocketM

+0

My bad. -1 возвращается, когда клиент закрывает соединение. Он может вернуть ноль, но вам нужно играть с блокировкой. Подробнее здесь: http://docs.oracle.com/javase/7/docs /api/java/nio/channels/SocketChannel.html#read(java.nio.ByteBuffer) – Leo