我想用socket编一个文件互传.已经实现文件重客户端发到服务端。问题是服务器的read是阻塞的,必须要客户端关闭我才可以读。可是我还必须要再用到客户端。请教方法。

解决方案 »

  1.   

    服务器的read方法确实是阻塞的,但是这个和你客户端的发送有什么关系呢?各在各的线程里面运行,客户端不停的发,而服务器不停的收(只有在socket里面没有内容了,read方法才会阻塞在那里),所以根本不需要关闭客户端啊(你可以自己定义一个结束命令,在你文件传输完成后就向服务器发送这个命令,而服务器收到这个命令后就知道传输结束,最后双方断开socket)。
      

  2.   

    问题问得不明白?
    什么叫“服务器的read是阻塞的,必须要客户端关闭我才可以读”
      

  3.   

    先谢谢大家,源代码如下。阻塞问题都过设置标记已解决。可现在的问题是读一次文件写了好多次。还有我写的结束标记感觉不太好,希望大家给点意见。
    package com.sun.net3;import java.io.*;
    import java.net.*;
    import java.util.ArrayList;
    public class FileServer {
    private ServerSocket servSck;
    private Socket cliSck;
    static ArrayList al=new ArrayList();

    public static void main(String[] args) {
    FileServer fs=new FileServer();
    try {
    fs.init();
    } catch (IOException e) {
    e.printStackTrace();
    }
    } public FileServer() {
    try {
    servSck=new ServerSocket(3000);
    System.out.println("服务器运行中,监听端口3000...");
    } catch (IOException e) {
    System.out.println("服务器运行出错");
    }
    }
    public void init() throws IOException{
    while(true){
    cliSck=servSck.accept();
    System.out.println("有客户连接,启动线程");
    System.out.println("接受文件中");
    transer tr=new transer(cliSck);
    al.add(tr);
    tr.start();
    }
    }

    }
    package com.sun.net3;import java.io.BufferedReader;
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.net.Socket;class transer extends Thread{
    private FileOutputStream fos;
    private Socket cliSck;
    private DataInputStream dis;
    private String msg;
    public transer(Socket cliSck){
    this.cliSck=cliSck;
    } public void run() { this.reClient();
    this.writeClient(cliSck);
    }
    public void  reClient() {
    try {
    dis=new DataInputStream(cliSck.getInputStream());
    String file=dis.readUTF();
    fos=new FileOutputStream(file,true);
    byte b[]=new byte[1024];
    int n=0;
    while(dis.readByte()!=0){
    System.out.println(1);
    n=dis.read(b);
    fos.write( b,0,n);
    fos.flush();
    }
    System.out.println(n);
    fos.close();
    // dis.close();
    // cliSck.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    public void writeClient(Socket client) {
    try {
    OutputStream os = client.getOutputStream();
    DataOutputStream dos = new DataOutputStream(os);
    String msg = "这是服务器做出的回答";
    dos.writeUTF(msg);
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }
    package com.sun.net3;import java.io.*;
    import java.net.*;import javax.swing.*;import com.sun.xml.bind.marshaller.DataWriter;public class FileClient {
    private static FileInputStream fis;
    private static Socket cliSck;
    private static DataOutputStream dos;
    public static void main(String[] args) {
    FileClient fc=new FileClient();
    try {
    cliSck = new Socket("localhost", 3000);
    JFileChooser jf=new JFileChooser();
    jf.showOpenDialog(null);
    File file=jf.getSelectedFile();
    fc.sedServer(file);
    fc.readServer();
    } catch (UnknownHostException e) {
    } catch (IOException e) {
    }

    } public  void sedServer(File file) {
    try {
    dos=new DataOutputStream(cliSck.getOutputStream());
    dos.writeUTF(file.getAbsolutePath());
    dos.flush();
    fis = new FileInputStream(file);
    byte[] b = new byte[1024];
    int n;
    while ((n = fis.read(b))!=-1) {
    dos.writeByte(1);
    System.out.println(n);
    dos.write(b,0,n);
    dos.flush();
    }
    dos.writeByte(0);
    fis.close();
    // dos.close();
    // cliSck.close();

    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    public void readServer(){
    try {
    InputStream is=cliSck.getInputStream();
    DataInputStream di=new DataInputStream(is);
    System.out.println("服务器的回复"+di.readUTF());
    // dos.close();
    // cliSck.close();

    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }