服务端:ServerSocket server = new ServerSocket(9527);客房端:Socket socket = new Socket(IP,9527);问题:传输一个,十个,百个文件都没事,可是现在要传一个文件夹里面有上百万个文件,每次传完一个文件就要重新执行
new Socket(IP,9527);一变,次数多了会有一异常出现,现在想有没有办法只实现一次new Socket(IP,9527);(把客户端与服务端连接建立后)就利用这一个连接传多个文件?不在for循环里写连接代码?

解决方案 »

  1.   

    for(File f : fileList)呢?
      

  2.   

    为什么要重新执行new Socket(IP,9527)
    好像没必要吧~
      

  3.   

    你这样老new socket,再牛逼的电脑,连接缓存都要搞没了
    你在外面定义好一个socket,和输入输出流
    new 一次,以后重用
    所有文件发完了再关闭。
      

  4.   

    你不会把Socket写在for循环里了吧- -!
    客户端就写一个Socket连接,用BufferedReader从键盘接收你要传的文件或文件夹,然后用if进行判断,如果你要传的类型是文件,那好,直接用输入输出流进行复制,如果是文件夹,那就用for循环对文件夹进行遍历,是文件就复制文件,是文件夹的就按照文件夹的名字新建文件夹
      

  5.   

    发送端和接收端都有一个while循环 通过in.read(buf))!=-1退出
    如果不重新连一下服务,用一个连接的话,发送端和接收端怎么判断什么时候接收新的文件?
      

  6.   

    发送方:int t = 0;
            while((ch = fis.read(buf))!=-1) {
              t += ch;
              out.write(buf,0,ch);
              if(t == (int)f.length()) {
                break;
              }
            }
    接收方:while((ch = in.read(buf))!=-1) {
                len += ch;
                DiaInfo.pb1.setValue(len);
                DiaInfo.pb1.setString(len+"/"+size);
                fos.write(buf, 0, ch);
                if(len == size) {
                  break;
                }
              }
      

  7.   

    无论是发送还是接受方都不要重复的new socket,
    第一次使用时判断是否为空,为空才new,所有的任务做完了,才能关闭。
    你把握这一点,程序就OK了用while(true){
    Thread.sleep(1000l);
    if(inputStream.available()>0){
    //判断有数据过来,接收}
    }
      

  8.   

    自己设置一个文件分隔标识吧,搞复杂一些,当发送一个文件结束后,将该分隔标识发出去,客户端读到这一行就表示一个文件结束,则开始读取下个文件
    如果觉得土,可以看看,一些FTP的源码如何处理的。
      

  9.   

    发送端用 out.writeUTF("end");表示一份文件完成,开发送下一份文件
    接收端:
    while((ch = in.read(buf))!=-1) {
                  len += ch;
                  DiaInfo.pb1.setValue(len);
                  DiaInfo.pb1.setString(len+"/"+size);
                  fos.write(buf,0,ch);
                  fos.flush();
                  if("end".equals( in.readUTF())) {
                    System.out.println("关闭");
                    break;
                  }
              }
    这样写不行了,只要运行到"end".equals( in.readUTF())这句就报错malformed input around byte
    应该怎么做标记?
      

  10.   


    发送方
    dos.writeInt(files.size());//文件个数
    for(File f:files){
       dos.writeUTF(f.getName());//文件名
       dos.writeLong(f.length());//文件长度
       dos.write(...);//文件内容
    }接收方
    int n = dis.readInt();//文件个数
    for(int i=0;i<n;i++){
       String filename = dis.readUTF();//文件名
       long length = dis.readLong();//文件长度
       dis.read(...);//读取length长度的字节
       ...//保存文件
    }
      

  11.   

    嘿嘿ie 顶个 虽然搞Java 但是还没用的过socket
      

  12.   

    实在不行就搞个ZipInoutStream。按顺序把文件写到ZipInoutStream中,在另一端解压缩就行。或者自己定义一个解析规定。
    贴上我的代码。这个还没整理过。作用是从客服端往服务器端发送文件。
    客服端代码package net;import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileFilter;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipOutputStream;/**
     * @author Life
     *发送文件的客户端
     */
    public class FileSendClient {
    protected String hostIP;
    protected int hostPort;
    protected OutputStream socketInS;
    private Socket client; public FileSendClient(String ip, int portNumber) {
    this.hostIP = ip;
    this.hostPort = portNumber;
    } /**
     * 建立连接
     */
    public void setUpConnection() {
    try {
    client = new Socket(hostIP, hostPort);
    socketInS = client.getOutputStream();
    } catch (UnknownHostException e) {
    throw new RuntimeException(e.toString());
    } catch (IOException e) {
    throw new RuntimeException(e.toString());
    } } /**
     * @param files
     * 用zip流发送多个文件
     * 
     */
    public void sendFile(File[] files) {
    BufferedInputStream fileReader = null;
    ZipOutputStream zos = new ZipOutputStream(socketInS);
    BufferedOutputStream socketWriter = new BufferedOutputStream(zos);
    byte[] buff = new byte[8192];
    int c = 0;
    try {
    for (File file : files) {
    fileReader = new BufferedInputStream(new FileInputStream(file));
    zos.putNextEntry(new ZipEntry(file.getName()));
    while ((c = fileReader.read(buff)) != -1) {
    socketWriter.write(buff, 0, c);
    }
    socketWriter.flush();
    try {
    if (fileReader != null)
    fileReader.close();
    } catch (IOException e) {
    System.out.println("Error closing fileReader" + e);
    }
    }
    } catch (IOException e) {
    e.printStackTrace();
    } finally {
    try {
    if (socketWriter != null )
    socketWriter.close();
    } catch (IOException e) {
    System.out.println("Error closing socketWriter" + e);
    }finally{
    if(client != null && client.isConnected()){
    try {
    client.close();
    } catch (IOException e) {
    System.out.println("Error closing socket" + e);
    }
    }
    } } } public static void main(String[] args) {
    FileSendClient fileSendClient = new FileSendClient("127.0.0.1", 3000);
    fileSendClient.setUpConnection();
    File[] files = new File("D:\\send").listFiles(new FileFilter() {
    public boolean accept(File pathname) {
    return pathname.isFile();
    }
    });
    fileSendClient.sendFile(files); }
    }服务器端代码:package net;import java.io.IOException;
    import java.net.BindException;
    import java.net.ServerSocket;
    import java.net.Socket;
    /**
     * @author Life
     *文件接收服务器
     */
    public class FileReceiveServer {
    protected int listenPort;
    private int maxConnection; public FileReceiveServer(int listenPort,int maxConnection) {
    this.listenPort = listenPort;
    this.maxConnection = maxConnection;
    }

    /**
     * 建立监听端口 
     */
    public void setUpConnection(){
    for(int i = 0; i < maxConnection; i++){
    new Thread(new FileReceiverHandle(),"handle"+i).start();
    }


    } /**
     * 接收文件客户端的连接
     */
    public void acceptConnection() {
    try {
    ServerSocket server = new ServerSocket(listenPort);
    Socket incomingSocket = null;
    while (true) {
    incomingSocket = server.accept();
    handlerConnection(incomingSocket);
    }
    } catch (BindException e) {
    e.printStackTrace();
    } catch (IOException e) {
    e.printStackTrace();
    } } /**
     * @param incomingSocket
     * 处理接收到的连接(socket)
     */
    private void handlerConnection(Socket incomingSocket) {
    FileReceiverHandle.processConnection(incomingSocket);

    } public static void main(String[] args) {
    FileReceiveServer fileReceiveServer = new FileReceiveServer(3000,5);
    fileReceiveServer.setUpConnection();
    fileReceiveServer.acceptConnection();
    }}package net;import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.Socket;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipInputStream;/**
     * @author Life
     *文件接收处理程序
     */
    public class FileReceiverHandle implements Runnable {
    private static List<Socket> socketsPool = new LinkedList<Socket>();
    private Socket connection = null;

    /**
     * @param incomingSocket
     * 降接收到的连接放到一个池中
     * 
     */
    public static void processConnection(Socket incomingSocket) {
    synchronized (socketsPool) {
    socketsPool.add(socketsPool.size(), incomingSocket);
    socketsPool.notifyAll();
    }
    } /**
     * 按zip流解码获取接收到的流
     */
    public void handlerConnection() {
    InputStream inputFromSocket = null;
    BufferedOutputStream fileWriter = null;
    BufferedInputStream socketReader = null;
    byte[] buff = new byte[8192];
    int c = 0;
    try {
    inputFromSocket = connection.getInputStream();
    ZipInputStream zis = new ZipInputStream(inputFromSocket);
    socketReader = new BufferedInputStream(zis);
    ZipEntry e = null;
    while ((e = zis.getNextEntry()) != null) {
    System.out.println(e.getName());
    fileWriter = new BufferedOutputStream(new FileOutputStream(
    new File("D:\\receive\\" + e.getName())));
    while ((c = socketReader.read(buff)) != -1) {
    fileWriter.write(buff, 0, c);
    }
    try {
    fileWriter.close();
    } catch (IOException e1) {
    e1.printStackTrace();
    }
    }
    } catch (IOException e) {
    e.printStackTrace();
    } finally {
    try {
    if (socketReader != null) {
    socketReader.close();
    }
    } catch (IOException e) {
    e.printStackTrace();
    }finally{
    try{
    if(connection != null){
    connection.close();
    }
    }catch(IOException e){
    e.printStackTrace();
    }
    } }
    } /* 
     * 处理池中的连接
     */
    public void run() {
    while (true) {
    synchronized (socketsPool) {
    while (socketsPool.isEmpty()) {
    try {
    socketsPool.wait();
    } catch (InterruptedException e) {
    return;
    }
    }
    connection = socketsPool.remove(socketsPool.size() - 1);
    }
    handlerConnection();
    }
    }}
      

  13.   

    只要双方都关闭了Socket,那么不应该出现问题的
      

  14.   

    在来一个BteBuffer的,但没实现NIO这个功能。NIO不太会,呵呵。代码没注释,写的很粗糙。就写了基本功能。
    客户端package nioserver;import java.io.File;
    import java.io.FileFilter;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.net.SocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.FileChannel;
    import java.nio.channels.SocketChannel;public class ChannelClient {
    private SocketChannel sc;
    private String hostIp;
    private int hostPort; public ChannelClient(String hostIp, int port) {
    this.hostIp = hostIp;
    this.hostPort = port;
    } private void setUpConnection() {
    try {
    SocketAddress remote = new InetSocketAddress(hostIp, hostPort);
    sc = SocketChannel.open();
    sc.connect(remote);
    } catch (IOException e) {
    throw new RuntimeException(e);
    }
    } private void sendFiles(File[] files) {
    FileChannel fileChannel = null;
    try {
    for (int i = 0;i < files.length; i++) {
    byte[] namebyte = files[i].getName().getBytes("UTF-8");
    long size = files[i].length();
    int nameLength = namebyte.length;
    fileChannel = new FileInputStream(files[i]).getChannel();
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    buffer.clear();
    buffer.putInt(4+8+nameLength);
    buffer.putInt(nameLength);
    buffer.put(namebyte);
    buffer.putLong(size);
    buffer.flip();
    while(buffer.hasRemaining()){
    sc.write(buffer);
    }
    long count = 1024*1024;
    long read = 0L;
    while(read < size){
    if(size - read < count)
    count = size - read;
    read += fileChannel.transferTo(0+read, count, sc);
    System.out.println("read:"+read);
    }
    fileChannel.close();
    if(i < files.length -1){
    sc.write(ByteBuffer.wrap(new byte[]{1}));
    System.out.println(1);
    }
    else
    sc.write(ByteBuffer.wrap(new byte[]{0}));
    }

    sc.close();
    } catch (FileNotFoundException e) {
    e.printStackTrace();
    } catch (IOException e) {
    e.printStackTrace();
    }
    } public static void main(String[] args) {
    ChannelClient client = new ChannelClient("127.0.0.1", 3000);
    client.setUpConnection();
    File[] files = new File("D:\\send").listFiles(new FileFilter() {
    public boolean accept(File pathname) {
    return pathname.isFile();
    }
    });
    client.sendFiles(files);
    }}
    服务器端package nioserver;import java.io.FileOutputStream;
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.net.SocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.FileChannel;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;public class FilesChannelServer {
    private String fileName = null;
    private long fileSize = 0L;
    private int hostPort;
    private ServerSocketChannel ssl = null;
    private SocketChannel clientChannel = null;
    private ByteBuffer buffer = null; public FilesChannelServer(int port) {
    this.hostPort = port;
    } private void setUpConnection() {
    try {
    ssl = ServerSocketChannel.open();
    SocketAddress address = new InetSocketAddress("127.0.0.1", hostPort);
    ssl.socket().bind(address);
    System.out.println("bind.....");
    } catch (IOException e) {
    e.printStackTrace();
    }
    } private void parseHead(int headlength) {
    buffer = ByteBuffer.allocate(headlength);
    try {
    while(buffer.position() < buffer.capacity())
      clientChannel.read(buffer);
    buffer.flip();
    byte[] filenamebyte = new byte[buffer.getInt()];
    buffer.get(filenamebyte);
    fileName = new String(filenamebyte,"UTF-8");
    fileSize = buffer.getLong();
    } catch (IOException e) {
    e.printStackTrace();
    }
    } private void parseBody(long size) {
    long read = 0L;
    long count = 8192;
    FileChannel fileChannel = null;
    try {
    fileChannel = new FileOutputStream("D:\\receive\\" + fileName)
    .getChannel();
    System.out.println(fileName);
    while (read < size) {
    if (size - read < count)
    count = size - read;
    read += fileChannel
    .transferFrom(clientChannel, 0 + read, count);
    } } catch (IOException e) {
    e.printStackTrace();
    }finally{
    try {
    fileChannel.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    } private int parse() {
    int i = 0;
    try {
    buffer = ByteBuffer.allocate(4);
    while(buffer.position() < buffer.capacity())
    clientChannel.read(buffer);
    buffer.flip();
    parseHead(buffer.getInt());
    parseBody(fileSize);
    buffer = ByteBuffer.allocate(1);
    while(buffer.position() < buffer.capacity())
    clientChannel.read(buffer);
    buffer.flip();
    i = buffer.get();
    } catch (IOException e) {
    e.printStackTrace();
    }

    return i;
    } private void acceptConnection() {
    while (true) {
    try {
    clientChannel = ssl.accept();
    int j = 1;
    while(j != 0){
    j = parse();
    System.out.println(j);
    }
    } catch (IOException e) {
    e.printStackTrace();
    } finally { try {
    if (clientChannel != null)
    clientChannel.close();
    } catch (IOException e) {
    e.printStackTrace();
    } } }
    } public static void main(String[] args) {
    FilesChannelServer cs = new FilesChannelServer(3000);
    cs.setUpConnection();
    cs.acceptConnection();
    }
    }这里说明下。可以说是我自定义的协议吧。
    一共分成6段
    在bytebuffer中第一个4个byte,存放第二段到地四段的byte长度
    第二段,四个byte长度是文件名转换成byte数组的长度(file.getName().getBytes("UTF-8").length)
    第三段,存放文件名转换的byte(file.getName().getBytes("UTF-8"))
    第四段,8个bte存放文件的大小(file.getSize())
    第五段,存放文件的byte形式,
    第六段,1个byte长度,如果还有后续的文件存放1,如果文件传送完了就存放0
      

  15.   

    传输这么多文件,为什么不用FTP啊。