我需要一个ClientSocket和一个ServerSocket,在两者之间进行传送文件,具体要求是先是Client传送到Server端,Server处理完数据后再传送到Client端.我现在的程序Client端能传送到Server过去,但是Server传送不回来,每次Client接收的时候提示:Socket Closeed,但是我人为的延迟也收不回来,哪位高手请指点一二..不胜感激

解决方案 »

  1.   

    你要在客户端建立一个socket来接受阿看看你的代码,功能很好实现的
      

  2.   

    这个是Client的程序:        DataInputStream dis = null;
            DataOutputStream dos = null;        DataInputStream diss = null ;
            DataOutputStream doss = null ;
            Socket ClientSocket = null;
            String strIp = "127.0.0.1" ;
            String strPort = "8001" ;
            try {
                ClientSocket = new Socket(InetAddress.getByName(strIp), Integer.parseInt(strPort));
                ClientSocket.setSoTimeout(60000);
                //创建Socket的输入输出流
                OutputStream ops = ClientSocket.getOutputStream();
                InputStream ips = ClientSocket.getInputStream();            //  为发送准备
                dis = new DataInputStream(new BufferedInputStream(new FileInputStream(zipfile)));
                dos = new DataOutputStream(new BufferedOutputStream(ops));            
                File file = new File(zipfile);
                int iSize = Integer.parseInt(String.valueOf(file.length()));
                byte[] buf = new byte[iSize];
                while ((dis.read(buf)) != -1) {
                    dos.write(buf, 0, buf.length);
                }
                System.out.println("客户端传输完毕");
                dos.close();            // 为接收准备
                BufferedInputStream br = new BufferedInputStream(ips);
                //以DataInputStream来包装字节缓冲输入流
                diss = new DataInputStream(br);
                //以DataOutputStream来包装字节缓冲输出流
                doss = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(zipAnsw)));
                byte[] bufr = new byte[1024];
                //网络传输都是以字节的方式传递的
                while ((diss.read(bufr,0,bufr.length)) != -1) {[red]每次都是在这个地方就异常,提示Socket Closed[/red]
                    //一边读,一边写
                    doss.write(bufr, 0, bufr.length);
                }
                System.out.println("fasdjlsa:"+ClientSocket.isConnected());
                System.out.println("客户端接收完毕");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    dis.close();
                    dos.close();
                    diss.close();
                    doss.close();
                    ClientSocket.close();
                } catch (IOException ex) {ex.printStackTrace();}
            }
    服务端的程序是:
    首先建立一个阻塞SocketServer:import java.util.zip.*;
    import java.io.IOException;
    import java.net.Socket;
    import java.net.ServerSocket;
    import java.io.*;public class Server {
        public Server() {
        }    public static void main(String[] a) {
            Socket s = null;
            ServerSocket Server = null;
            String file = "D:\\Socket\\Server\\question.zip";
            try {
                //判断是否在命令行的方式传递了输出文件的文件名
                Server = new ServerSocket(8001);
                System.out.println("Server Started ...");
                while (true) {
                    //接受客户端的请求发送文件,没有请求则阻塞
                    s = Server.accept();
                    //以重新启动一个线程的方式,取得客户端发送的文件
                    new Thread(new Servicer(s, file)).start();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    s.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
    然后处理程序为:import java.io.*;
    import java.net.Socket;public class Servicer implements Runnable {
        public Servicer() {
        }    Socket server = null;
        String fileName = null;
        String ClientPort = "0000";
        String IP = "127.0.0.1" ;
        String PORT = "0000" ;
        //传递文件名和Socket
        Servicer(Socket s, String fileName) {
            this.server = s;
            this.fileName = fileName;    }    public void run() {
            DataInputStream dis = null;
            DataOutputStream dos = null;        DataInputStream disa = null;
            DataOutputStream dosa = null;        //创建Socket的输入输出流
            try {
                this.IP = server.getInetAddress().toString() ;
                this.PORT = String.valueOf(server.getPort()) ;
                System.out.println("地址是:" +  this.IP);
                System.out.println("端口是:" + this.PORT);
                
                InputStream ips = server.getInputStream();
                OutputStream ops = server.getOutputStream();
                BufferedInputStream br = new BufferedInputStream(ips);
                //以DataInputStream来包装字节缓冲输入流
                dis = new DataInputStream(br);
                //以DataOutputStream来包装字节缓冲输出流
                dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(fileName)));
                byte[] bufr = new byte[1024];
                //网络传输都是以字节的方式传递的
                while ((dis.read(bufr)) != -1) {
                    //一边读,一边写
                    dos.write(bufr, 0, bufr.length);
                }
                System.out.println("服务器端接收完毕");
                dis.close();
                dos.close();
                try {
                    String zipfile = "D:\\Socket\\Server\\answer.zip";                dis = new DataInputStream(new BufferedInputStream(new FileInputStream(zipfile)));
                    dos = new DataOutputStream(new BufferedOutputStream(ops));
        
                    File file = new File(zipfile);
                    int iSize = Integer.parseInt(String.valueOf(file.length()));
                    byte[] buf = new byte[iSize];
                    while ((dis.read(buf)) != -1) {
                        dos.write(buf, 0, buf.length);
                    }
                    dos.close();                System.out.println("服务器端传输完毕");
                } catch (IOException ex2) {
                    ex2.printStackTrace();
                }
                disa.close();
                dosa.close();
                Thread.sleep(2000);
            } catch (FileNotFoundException fe) {
                fe.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    dis.close();
                    dos.close();
                    disa.close();
                    dosa.close();
                    server.close();
                } catch (IOException ex) {}
            }
        }}
    请指教~~
      

  3.   

    如果我在客户端发送完以后没有dos.close();的话,客户端和服务器端就死锁掉,但是客户端发送完以后dos.close();的话,服务器端回传文件完毕以后客户端读取的时候提示Socket Close,请高手指点一二!!!
      

  4.   

    好长,你只是对结构的理解有问题,在线程中应该有一个循环来控制它的执行,应该这样一个结构:
    boolean FLAG = true;
    public void run()
    {
      建立连接
      ...
      while(FlAG)
      {
        打开流
        ...
        数据传输(接收)
        ...
        关闭流
        ...
        sleep(2000);
      }
      关闭连接
      ...
    }
    大概就这样,你可能有一个理解错误是觉得线程一旦启动,只要我们不关闭,它会一直存在并等待,其实不是这样,线程执行完run()中的代码后就会自动结束,所以只要在你的客户和服务端都加上循环,就OK了
      

  5.   

    补充一句,当需要关闭线程的时候,将FLAG = false就可以了
      

  6.   

    其实我现在的功能已经可以发送文件了,服务器端也可以往回写文件的,就是客户端收文件的时候提示Socket Closed.我知道run里面的代码执行完了以后线程就结束的
      

  7.   

    oh ,sorry!我又仔细看了一下你的代码,猜想你可能是在处理1对多的时候出了问题了,可以在main的主循环这样:
    Vector clientList = new Vector();
    while (true) 
    {
      //接受客户端的请求发送文件,没有请求则阻塞
      s = Server.accept();
      //以重新启动一个线程的方式,取得客户端发送的文件
      Thread currentThread = new Thread(new Servicer(s, file));
      currentThread.start();
      clientList.add(currentThread);
    }
    这样保证一个客户端有一个相应的服务线程为它服务,不会导致客户端发送完以后没有dos.close();,客户端和服务器端就死锁掉,服务器想干什么就到clientList找到相应的客户连接操作就OK了
      

  8.   


    感谢炮炮兄:不过这样子和我的程序有什么区别吗,不都是一样的吗,来了一个连接就启动一个线程,我现在的情况是在一个线程启动的情况下都不能传输文件(能传过去,不能传回来),在while ((dis.read(bufr)) != -1) {
    时会阻塞掉,麻烦你再看看.
      

  9.   

    其实你应该这么来看这个问题
    client发送File到server建立一个连接,传送完,关闭连接
    server处理文件,处理完后就新建一个连接到client,
    client启动一个socket来接受
    接收后关闭
      

  10.   

    先说和你程序的区别:你的程序只能针对一个客户服务,是属于一对一关系的,看这里
    while (true) 
    {
     //接受客户端的请求发送文件,没有请求则阻塞
     s = Server.accept();
     //以重新启动一个线程的方式,取得客户端发送的文件
     new Thread(new Servicer(s, file)).start();
    }
    当有一个连接请求的时候,都会生成一个新的Servicer对象,而原来的对象则被销毁,所以,应该在生成新对象的时候,把它保存到向量中,新的对象产生了,而原来的对象仍然生存,就可以完成一对多的服务;然后说流的问题,我不确定,因为没有这么做过,我建议你写一些简单的协议(姑且称为协议),在文件传输的时候就知道了文件的长度等信息,直接读指定长度,关于那个为什么不行我再查查书吧
      

  11.   

    谢谢:炮炮,启动线程这个地方我明白了可是在传输数据的过程中还是无法传送,还有请高手指点.谢谢:datalover(String lover(String loveme)) :
    那我client需要在WebLogic上运行,我就不能再启动ServerSocket了吧,可是如果我建立一个Socket对象的话,算是一个客户端,没法连接吧,请指点.