我的接收线程是这样写的public class ReceiveThread extends Thread { DataInputStream dataInputStream = null; int offset; int totalSize; boolean header = true; final static int HEADER_SIZE = 1; final static int BUFFER_SIZE = 1024; byte[] buffer = new byte[BUFFER_SIZE]; byte[] cache = new byte[BUFFER_SIZE * 64]; byte[] headerData = new byte[HEADER_SIZE]; public ReceiveThread(DataInputStream dataInputStream) {
this.dataInputStream = dataInputStream;
} public void run() {
try {
int available = 0;
while (dataInputStream != null
&& (available = dataInputStream.read(buffer)) > 0) { if ((offset + available) > cache.length)
cache = grow(cache, BUFFER_SIZE * 10); System.arraycopy(buffer, 0, cache, offset, available);
offset += available; if (header && offset >= 4) {
byte[] b = new byte[4];
System.arraycopy(cache, 0, b, 0, b.length);
totalSize = StockUtil.getInt4(b);
System.out.println("totalSize=" + totalSize);
header = false;
}
if (offset >= totalSize) {
byte[] data = new byte[totalSize - HEADER_SIZE];
System.arraycopy(cache, 4, headerData, 0, HEADER_SIZE);
System.arraycopy(cache, 4 + HEADER_SIZE, data, 0,
data.length);
System.out.println("fileType=" + headerData[0]
+ " data.length=" + data.length);
cache = reduce(cache, 4 + totalSize);
offset -= (4 + totalSize);
header = true;
}
}
} catch (Exception e) {
e.printStackTrace();
}
} public byte[] reduce(byte[] buffer, int off) {
byte[] data = new byte[buffer.length - off];
System.arraycopy(buffer, off, data, 0, data.length);
return data;
} public byte[] grow(byte[] buffer, int size) {
byte[] data = new byte[buffer.length + size];
System.arraycopy(buffer, 0, data, 0, buffer.length);
return data;
}
}长时间运行后,偶尔会报错哪位有更好的写法,贴一下

解决方案 »

  1.   

    咋这么复杂?   //接收字符串的
    class ClientRecieveThread extends Thread
    {
    Socket client;
    ClientRecieveThread(Socket s)
    {
    this.client = s;
    }
    public void run()
    {
    String recieve = "";
    try
    {
    Scanner in = new Scanner(client.getInputStream());
    while(!client.isClosed() && in.hasNextLine())
    {
    recieve = in.nextLine();
    ClientFrame.taChat.append(recieve + "\n");
    }
    ClientFrame.isServerOpen = false;
    ClientFrame.isConnect = false;
    client.close();
    } catch (IOException e)
    {
    e.printStackTrace();
    }
    }
    }
       
      

  2.   

    我要按自定义的报头描述来接收字节数组的,这样可以接收任意的数据了,不仅仅是字符串。
    我定义的报头是这样的,前4个字节为要接收的数据大小,后面一个字节描述数据类型,再后的是数据本身。
    问题找到了,判断接收大小的时候没有加上描述数据大小的4个字节,加上就没问题了
    if (offset >= (4 + totalSize))
      

  3.   

    就看你封包的时候toalsize中有没有包含包头的长度了,一般是没有的
      

  4.   

    Server端:package server;import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.ArrayList;public class ServerText {
        ServerSocket serversocket=null;
        Socket socket=null;
        ArrayList<Client> clients=new ArrayList<Client>();
        boolean con=false;
       public void start() {
           try {
            serversocket=new ServerSocket(8888);//设置服务器端口号
        } catch (IOException e) {
           System.out.println("服务器启动失败");//可能是当前的端口号已被占用
        }
        System.out.println("服务器启动成功");
        while(con==true) {
            try {
                socket=serversocket.accept();
                Client client=new Client();
                Thread t=new Thread(client);
                t.start();
                clients.add(client);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
       }
       
       class Client implements Runnable {
           DataInputStream in=null;
           DataOutputStream out=null;
           Client() {
                try {
                    in=new DataInputStream(socket.getInputStream());
                    out=new DataOutputStream(socket.getOutputStream());
                } catch(Exception ae) {
                    ae.printStackTrace();
                }
            }
           public void write(String str1) {
               try {
                    out.writeUTF(str1);
                    out.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
           }       public void run() {
               String str2="";
               while(con) {
                   try {
                    str2=in.readUTF();
                } catch (IOException e) {
                    System.out.println("客户端异常退出");
                    
                    try {
                        in.close();
                        out.close();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                    break;
                }
               }
           }
       }
       
       
       public static void main(String args[]) {
           ServerText servertext=new ServerText();
           servertext.start();
          for(int i=0;i<servertext.clients.size();i++) {
              servertext.clients.get(i).write("你妈叫你吃饭了");
          }
           
       }
       
    }
      

  5.   

    Server端:package client;import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.net.Socket;public class ClientText implements Runnable{
        Mythread mythread=null;
       Socket socket=null;
       boolean con=false;
       DataInputStream in=null;
       DataOutputStream out=null;
       public void connect() {
           try {
               socket=new Socket("127.0.0.1",8888);
                in=new DataInputStream(socket.getInputStream());
                out=new DataOutputStream(socket.getOutputStream());
                con=true;
            } catch (Exception ae) {
                ae.printStackTrace();
            }
       }
       public void run() {
           String str="";
           while(con) {
               try {
                str=in.readUTF();
            } catch (IOException e) {
                System.out.println("服务器端出错");
                try {
                    in.close();
                    out.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            System.out.println(str);
           }
       }
       class Mythread implements Runnable {
           public void run() {
               try {
                out.writeUTF("娃哈哈,O(∩_∩)O~");
            } catch (IOException e) {
                System.out.println("服务器端出错");
                try {
                    in.close();
                    out.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
           }
       }
       public static void main(String args[]) {
          for(int i=1;i<=10;i++) {
              ClientText clienttext=new ClientText();
              clienttext.connect();
              Thread t=new Thread(clienttext);
              t.start();
              Thread tt=new Thread(clienttext.mythread);
              tt.start();
          }
       }
    }
      

  6.   

    就看你封包的时候toalsize中有没有包含包头的长度了,一般是没有的
      

  7.   

    用阻塞方式读取,非常简单int totalSize = dataInputStream.readInt();
    dataInputStream.readFully(headerData);
    byte[] data = new byte[totalSize - HEADER_SIZE];
    dataInputStream.readFully(data);