Topic: 关于:socket的读写 ...

  Print this page

1.关于:socket的读写 ... Copy to clipboard
Posted by: terry39
Posted on: 2003-04-07 16:52

看过很多例子 也写了好几个试验过了
BufferedReader
PrintWriter
InputStreamReader
OutputStreamReader
...
好多 搞的我的头都乱了 ...

一个问题: 是否不用关对方采用那个类的对象来读写数据
我这方可以随便采用一个类来做 ?

我的试验结果好像不是 但我想 应该是 ...

2.Re:关于:socket的读写 ... [Re: terry39] Copy to clipboard
Posted by: jam
Posted on: 2003-04-14 12:41

You can refernece Java Cookbook. There are many good examples in Chapter 15 "Network Clients". And explain how to use. It's help me much.

3.Re:关于:socket的读写 ... [Re: terry39] Copy to clipboard
Posted by: huzorro
Posted on: 2003-04-14 13:33

如果你不介意多看几眼……
http://cn.sun.com/developers/onlineTraining/Programming/BasicJava2/socket.html

4.Re:关于:socket的读写 ... [Re: terry39] Copy to clipboard
Posted by: terry39
Posted on: 2003-04-15 12:25

看了

我还有一个问题:
若我以byte[]读 怎么知道结束了?

5.Re:关于:socket的读写 ... [Re: terry39] Copy to clipboard
Posted by: jiangns3000
Posted on: 2003-04-15 13:40

若网络传输是以二进制如byte为单位进行的,则当发方发送完二进制字节数据后,关闭流时JAVA会向流中写入一个流结束标记。接受方以二进制方式读取流时,比如:
int data;//注意data是int
data=AnyByteInputStream.read();
此时读入的是任意二进制字节数据。若读到流结束标记,则data值为-1。(这就是为什么data定义为int,data中-1不会与流中任何二进制数据混淆。)
故代码是:
while((data=AnyByteInputStream.read())!=-1)
对data中字节数据进行处理。

6.Re:关于:socket的读写 ... [Re: terry39] Copy to clipboard
Posted by: terry39
Posted on: 2003-04-15 14:18

我是这样写的
 ... run() { readBuf(); } ...

...

  public void readBuf(){
    byte[] bytebuf=new byte[1024];
    int i=0;
    while(true){
      try{
        i=in.read(bytebuf); //读到 byte[] bytebuf中
      }catch(IOException e){
        //...
      }
    }
  }


若 server 没有数据传来 为何 还一直在 while() ... ? 不是会停止的么?
( 以前用 BufferedReader.readLine() 会出现停下的情况 所以用线程 ...)

7.Re:关于:socket的读写 ... [Re: terry39] Copy to clipboard
Posted by: jiangns3000
Posted on: 2003-04-15 15:08

read(bytebuf)实际上是调用read()进行的(JDK文档对此有说明),而字节流的read()是一个阻塞型的操作。当无数据可读则线程会阻塞在此处(while中的in.read(bytebuf))。这是对的呀。你的问题到底是什么呢?

8.Re:关于:socket的读写 ... [Re: terry39] Copy to clipboard
Posted by: terry39
Posted on: 2003-04-15 15:45

题外话:今天上cjsdn怎么一阵断一阵的?

我实际上碰到的问题:

while(true){
try{
i=in.read(bytebuf);
System.out.println("had read bytebuf and do smth ...");
}catch(){
//...
}
}

运行的时候 终端显示无数个 had read bytebuf and do smth ...
也就是说 没有阻塞. ... Sad

9.Re:关于:socket的读写 ... [Re: terry39] Copy to clipboard
Posted by: jiangns3000
Posted on: 2003-04-15 16:11

我终于准确知道你的问题了。这个原因是:read(bytebuf)在读时,遇到某种Exception而停止阻塞。比如:发方发送完数据后即关闭流及socket。此时就会有如此现象。主要是你的代码写得有点儿欠佳,改为如下即可解决问题:(按你程序中的意图)
while( (i=in.read(bytebuf))!=-1)
{ do something ;}
当然放在try{}块中。

10.Re:关于:socket的读写 ... [Re: terry39] Copy to clipboard
Posted by: terry39
Posted on: 2003-04-15 16:17

非常感谢 jiangns3000大哥,我还有个问题:

如何创建一块内存空间 可以一直往里面添byte[] 并且自动接在后面在一定条件满足时 可以把这快内存空间作为一个byte[] 使用用socket发送出去 ...
其实也就是缓冲的问题 ... 主要是能控制具体什么条件才发生数据 ...

我尝试了 ByteBuffer 没有成功 ..

ByteBuffer bytebuf=ByteBuffer.allocate(1024); //allocateDirect(1024)也不行
bytebuf.put("new String to send\n".getBytes());
bytebuf.put("another string to send\n".getBytes());

byte[] buff=new buff[1024]; //如何取出到一个byte[]里面呢?
bytebuf.get(buff); //我尝试了这两个步骤

//若取出的是byte[],则我可以输出到终端
System.out.println(new String(buff));

//结果:失败

11.Re:关于:socket的读写 ... [Re: terry39] Copy to clipboard
Posted by: jiangns3000
Posted on: 2003-04-15 16:49

你所说的失败指什么含义呢?是输出结果不对吧?从你程序片断看,这个片断的结果(bytebuf.get(buff)中)buff的结果不对。应该:在bytebuf.get(buff); 之前加上一句: bytebuf.rewind() ;即可。

12.Re:关于:socket的读写 ... [Re: terry39] Copy to clipboard
Posted by: terry39
Posted on: 2003-04-15 17:02

是的...现在可以了 ...

若想知道具体放入了多少length的byte 则如何?
我方法 position() 不过 好象不对 多了四个字节 ... why???

------------------------------------------------------------------------------------------------

我查到原因了 是我程序里多了条语句 ...
非常感谢 jiangns3000 大哥 的帮助 ....

13.Re:关于:socket的读写 ... [Re: terry39] Copy to clipboard
Posted by: jiangns3000
Posted on: 2003-04-15 17:11

position()应该是对的。请仔细确认一下。

14.Re:关于:socket的读写 ... [Re: terry39] Copy to clipboard
Posted by: jiangns3000
Posted on: 2003-04-15 17:20

例如:
int len;
ByteBuffer bytebuf=ByteBuffer.allocate(1024);

bytebuf.put("new\n".getBytes());
bytebuf.put("another\n".getBytes());

len=bytebuf.position() ;//个数应该正确

bytebuf.rewind() ;

byte[] buff=new byte[1024]; //如何取出到一个byte[]里面呢?

bytebuf.get(buff,0,len ); //

//System.out.println(new String(buff));

for(int i=0;i<len ;i++)
System.out .print((char)buff[i]) ;
//结果正确

15.Re:关于:socket的读写 ... [Re: terry39] Copy to clipboard
Posted by: terry39
Posted on: 2003-04-15 17:23

是的 ....
我是这样的:

byte[] buff=new byte[len];
bytebuf.rewind();
bytebuf.get(buff);

我这样做的话 是否有什么缺点?

16.Re:关于:socket的读写 ... [Re: terry39] Copy to clipboard
Posted by: jiangns3000
Posted on: 2003-04-15 18:02

我想是正确的。

17.Re:关于:socket的读写 ... [Re: terry39] Copy to clipboard
Posted by: terry39
Posted on: 2003-04-16 10:17

还有一个小问题:
你上面说:
[qoute]
我终于准确知道你的问题了。这个原因是:read(bytebuf)在读时,遇到某种Exception而停止阻塞。比如:发方发送完数据后即关闭流及socket。此时就会有如此现象。主要是你的代码写得有点儿欠佳,改为如下即可解决问题:(按你程序中的意图)
while( (i=in.read(bytebuf))!=-1)
{ do something ;}
当然放在try{}块中。
[/qoute]

是否 遇到Exception时,线程自动结束,从而不需要在处理Exception时调用线程的 destory() 方法呢?

18.Re:关于:socket的读写 ... [Re: terry39] Copy to clipboard
Posted by: jiangns3000
Posted on: 2003-04-16 10:47

不是。只是read()不再阻塞(read()的任务完成),与线程自动结束没有关系。

19.Re:关于:socket的读写 ... [Re: terry39] Copy to clipboard
Posted by: terry39
Posted on: 2003-04-16 18:01

这些问题都是我做socket时 衍生出来的 ...


public class BaseClient{
private Socket client;
...
private InputStream in;
... ... out;

private Thread getDataThread;

public BaseClient(String hostAddr, int hostPort){
this.hostAddr=hostAddr;
...

//创建一个读数据的线程
getDataThread = new Thread(){
public void run(){
while((len=in.)!=-1){ getDataFunction(buff); } //循环不停的读 [1]
}
}
...
}

//激活连接
public setConnect(){
try{
client=new Socket(...);
in=client.getInputStream();
out=client.getOutputStream();
}catch(...){}
}

//发送数据的方法 ...
public void sendDataOut(byte[] buff){
out.write(buff);
out.flush();
}

//得到数据时 执行的函数 ...
public void getDataFunction(byte[] buff){
//供重载
}

//以及一些发生错误时 会被调用的方法 供重载
...(略)
}


在 [1] 处, 若发生了Exception 是否线程自动结束?(好象退出了while循环)
若不是自动结束 我改如何操作 以停止线程? thread.destory() 么?

我是想 能够随时停止、启动 socket

20.Re:关于:socket的读写 ... [Re: terry39] Copy to clipboard
Posted by: jiangns3000
Posted on: 2003-04-16 18:28

若你的线程中run()代码:
public void run()
{
while((len=in.read(bytebuf))!=-1)
{ getDataFunction(buff); }
}
只有如上一条while语句,则当发方发完数据且关闭流与楼台socket时,
read(bytebuf)返回-1,while语句结束,整个run()代码执行结束。故线程停止。当发生Exception时,若相应的catch()在while之外,则while结束,run()代码执行完,线程结束。因此线程结束是因为其中代码运行完毕。

21.Re:关于:socket的读写 ... [Re: terry39] Copy to clipboard
Posted by: terry39
Posted on: 2003-04-17 08:55

以下代码 编译通过 执行出错 不知道为什么 ...

import java.net.*;
import java.io.*;

public class BaseClient{

  private static final int UNKNOWN_HOST_ERROR=0;
  private static final int CREATE_IO_ERROR=1;
  private static final int GET_DATA_ERROR=2;
  private static final int SEND_DATA_ERROR=3;
    
  private Socket client;

  private String hostAddr=null;
  private int hostPort=0;

  private InputStream in;
  private OutputStream out;  

  private Thread getDataThread;
  
  private boolean connectionStatus=false;
  
  private boolean stopThread=false;
  
  /**
   *read in buffer
   */
  private byte[] buff;  
  private int len;
  
  public BaseClient(String hostAddr,int hostPort){
    this.hostAddr=hostAddr;
    this.hostPort=hostPort;
    createReadDataThread();
  }
  
  private void createReadDataThread(){
    getDataThread=new Thread(){
      public void run(){
        while(!stopThread){
          try{
            while((len=in.read(buff))!=-1){ // 出错在这里 ... 什么原因呢?
              getDataIn(buff);
            }
          }catch(IOException e){
            disconnect(GET_DATA_ERROR);
          }
        }
      }
    };  
  }
  
  private void disconnect(int connectionError){
    connectionStatus=false;
    try{
      in.close();
      out.close();
      client.close();
      stopThread=true;
    }catch(IOException e){}
    switch (connectionError){
      case UNKNOWN_HOST_ERROR:
        connectionError();
        break;
      case CREATE_IO_ERROR:
        connectionError();
        break;
      case GET_DATA_ERROR:
        getDataError();
        break;
      case SEND_DATA_ERROR:
        sendDataError();
    }
  }
  
  
   //////////////////////////////////////
   ///////// Connection Methods /////////
   //////////////////////////////////////
  
  
  public void setConnect(){
    try{
      client=new Socket(hostAddr,hostPort);
      out=client.getOutputStream();
      in=client.getInputStream();

      getDataThread.start(); // 在这里才启动 线程
      
      connectionStatus=true;
      connectionReady();
      
    }catch(UnknownHostException unkhex){
      disconnect(UNKNOWN_HOST_ERROR);
    }catch(IOException ioex){
      disconnect(CREATE_IO_ERROR);
    }
  }
  
  public void setDisconnect(){
    connectionStatus=false;
    try{
      in.close();
      out.close();
      client.close();
      stopThread=true;
    }catch(IOException e){}
  }
  
  /**
   *send data out method
   */
  public void sendDataOut(byte[] buff){
    try{
      out.write(buff);
      out.flush();
    }catch(IOException e){
      disconnect(SEND_DATA_ERROR);
    }
  }
  
  public InputStream getInputStream(){
    return in;
  }
  
  public OutputStream getOutputStream(){
    return out;
  }
  

   //////////////////////////////////////
   ///////// Connection Events //////////
   //////////////////////////////////////
  
  public void connectionReady(){
    System.out.println("lxd.BaseClient.connectionReady()");
  }
    
  public void connectionError(){
    System.out.println("lxd.BaseClient.connectError()");
  }
  
  public void sendDataError(){
    System.out.println("lxd.BaseClient.sendDataError()");
  }
  
  public void getDataError(){
    System.out.println("lxd.BaseClient.geDataError()");
  }
  
  public void getDataIn(byte[] buff){
    System.out.println("lxd.BaseClient.getDataIn()");
  }
//main()
public static void main(String[] args){
BaseClient baseclient=new BaseClient("192.168.0.22",1080);
baseclient.setConnect();
}  
}


运行出错信息:

lxd.BaseClient.connectionReady()
java.lang.NullPointerException
at java.net.SocketInputStream.read(SocketInputStream.java:90)
at BaseClient$1.run(BaseClient.java:42)
Press any key to continue...

22.Re:关于:socket的读写 ... [Re: terry39] Copy to clipboard
Posted by: terry39
Posted on: 2003-04-17 10:24

查出原因:

byte[] buff; //这里错了 ... 一定要分配好长度

该成

byte buff=new byte[1024]; //可以了


我 参考了:
read
public int read(byte[] b,
int off,
int len)
throws IOExceptionReads up to len bytes of data from the input stream into an array of bytes. An attempt is made to read as many as len bytes, but a smaller number may be read, possibly zero. The number of bytes actually read is returned as an integer.
This method blocks until input data is available, end of file is detected, or an exception is thrown.

If b is null, a NullPointerException is thrown.

If off is negative, or len is negative, or off+len is greater than the length of the array b, then an IndexOutOfBoundsException is thrown.

If len is zero, then no bytes are read and 0 is returned; otherwise, there is an attempt to read at least one byte. If no byte is available because the stream is at end of file, the value -1 is returned; otherwise, at least one byte is read and stored into b.

The first byte read is stored into element b[off], the next one into b[off+1], and so on. The number of bytes read is, at most, equal to len. Let k be the number of bytes actually read; these bytes will be stored in elements b[off] through b[off+k-1], leaving elements b[off+k] through b[off+len-1] unaffected.

In every case, elements b[0] through b[off] and elements b[off+len] through b[b.length-1] are unaffected.

If the first byte cannot be read for any reason other than end of file, then an IOException is thrown. In particular, an IOException is thrown if the input stream has been closed.

The read(b, off, len) method for class InputStream simply calls the method read() repeatedly. If the first such call results in an IOException, that exception is returned from the call to the read(b, off, len) method. If any subsequent call to read() results in a IOException, the exception is caught and treated as if it were end of file; the bytes read up to that point are stored into b and the number of bytes read before the exception occurred is returned. Subclasses are encouraged to provide a more efficient implementation of this method.

Parameters:
b - the buffer into which the data is read.
off - the start offset in array b at which the data is written.
len - the maximum number of bytes to read.
Returns:
the total number of bytes read into the buffer, or -1 if there is no more data because the end of the stream has been reached.
Throws:
IOException - if an I/O error occurs.
See Also:
read()


   Powered by Jute Powerful Forum® Version Jute 1.5.6 Ent
Copyright © 2002-2021 Cjsdn Team. All Righits Reserved. 闽ICP备05005120号-1
客服电话 18559299278    客服信箱 714923@qq.com    客服QQ 714923