简体   繁体   English

从套接字通道读取字符串

[英]Read string from socket channel

Hy, HY,

I have the following code: 我有以下代码:

    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());
            }  
          }
}

and the zodie static method which receive a string and return a string. zodie static方法接收一个字符串并返回一个字符串。

How can I get the string written into SocketChannel to pass it as argument to zodiac static method. 如何将字符串写入SocketChannel,以将其作为参数传递给十二生肖静态方法。

I mention that in the client side I send an array of bytes and I have checked and it's ok. 我提到在客户端,我发送了一个字节数组,我已经检查过了,没关系。

Client side: 客户端:

  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();

Sincerely, 真诚的

I get the server error: 我收到服务器错误:

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)

The issue was on the client side. 问题出在客户端。 I have used a charbuffer as a wraper 我使用了charbuffer作为包装器

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();

On the server side: 在服务器端:

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();

You problem is in line bb.get(a); 您的问题在bb.get(a)行中;

You specify 11 characters array as a parameter and thus method get() expects bb to contain 11 characters but it only contains 1. 您指定11个字符的数组作为参数,因此get()方法期望bb包含11个字符,但仅包含1个字符。

The reason is that when you write 11 characters to the socket they are not guaranteed to arrive all at once. 原因是当您向套接字写入11个字符时,不能保证它们一次全部到达。 They can arrive in small groups like 1 and than 10 or 5 and 6 etc. 他们可以像1到10或5和6之类的小团体到达。

You need to look and read from socket and check result of read() call. 您需要查看和读取套接字,并检查read()调用的结果。 Something along the lines: 大致情况:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM