本帖最后由 dnfpyz2012 于 2011-11-06 19:56:31 编辑

解决方案 »

  1.   

    因为你在发送文件的时候,直接把bw给关闭了,这样导致socket关闭,然后在接收的时候就会出现问题,而且你的server和client都不严谨,server程序很明显在并发的时候会出错,线程不能这样些,顺便附上我简单修改过的,表达能力不行,希望你能理解Serverpackage server;import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;public class Server {

    private int port;
    Server(int port) {
    this.port = port;
    }

        public void StartServer() {
            try {
             ServerSocket server = new ServerSocket(port);
                while (true) {
                 try{
                 new Thread(new ServerProcess(server.accept())).start();
                 }catch(Exception ex){
                 ex.printStackTrace();
                 }
                }
            } catch (IOException e) {
                System.out.println("ServerSocket创建失败!检查端口"+port+"是否被占用");
                e.printStackTrace();
            }    }
    }class ServerProcess implements Runnable{

    private static final String SEND_PATH = "D:/dos命令参数.txt";    //发送文件路径
    private static final String RECV_PATH = "D:/hello.java"; //接收文件路径

        private InputStream in;
        private OutputStream out;
        
    ServerProcess(Socket socket) {
    try {
    in = socket.getInputStream();
    out = socket.getOutputStream();
    } catch (IOException e) {
    e.printStackTrace();
    throw new RuntimeException("socket 错误!");
    }
    }
        ////////////////接收////////////////
        private void receive() {
         FileOutputStream fileOut = null;
            try {
                File file_receive = new File(RECV_PATH);
                fileOut = new FileOutputStream(file_receive);
                pipe(fileOut,in);
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
             if(null != fileOut){
             try {
    fileOut.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
             }
            }
            System.out.println("文件接收已完成!");
        }
        
    private void pipe(OutputStream out,InputStream in) throws IOException {
    byte[] buf = new byte[512];
    int len = 0;
    while((len = in.read(buf)) != -1) {
    out.write(buf,0,len);
    }
    }
    /////////////////////发送/////////////////////////
        private void send(){
            FileInputStream fileIn = null;
            try {
                File file_send = new File(SEND_PATH);
                fileIn = new FileInputStream(file_send);
                pipe(out,fileIn);
                System.out.println("文件发送已完成!");
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
             if(null != fileIn) {
             try {
    fileIn.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
             }
            }
        }
        @Override
        public void run() {
         try{
         send();
            receive();
         }finally{
         try {
    in.close();
    } catch (IOException e) {
    e.printStackTrace();
    }finally{
    try {
    out.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
         }
        }
    }Server启动代码 new Server(6666).StartServer();Clientpackage client;import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;public class Client {
    private static final String SEND_PATH = "D:/dos命令参数1.txt";
    private static final String RECV_PATH = "D:/hello1.java"; private InputStream in;
    private OutputStream out; Client(String host, int port) {
    try {
    Socket socket = new Socket(host, port);
    in = socket.getInputStream();
    out = socket.getOutputStream();
    } catch (UnknownHostException e) {
    System.out.println("无法找到主机:" + host);
    e.printStackTrace();
    throw new RuntimeException(e);
    } catch (IOException e) {
    System.out.println("可能是端口错误 :" + port);
    e.printStackTrace();
    throw new RuntimeException(e);
    }
    } // //////////////发送/////////////////////////
    private void send() {
    InputStream fileIn = null;
    try {
    fileIn = new FileInputStream(SEND_PATH);
    pipe(out, fileIn);
    System.out.println("文件发送完成");
    } catch (IOException e) {
    e.printStackTrace();
    }finally{
    if(null != fileIn) {
    try {
    fileIn.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    } // ///////////////////接收/////////////////////
    private void receive() {
    OutputStream fileOut = null;
    try {
    fileOut = new FileOutputStream(RECV_PATH);
    pipe(fileOut,in);
    System.out.println("文件接收已完成!");
    } catch (IOException e) {
    e.printStackTrace();
    }finally{
    if(null != fileOut){
    try {
    fileOut.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    } private void pipe(OutputStream out, InputStream in) throws IOException {
    byte[] buf = new byte[512];
    int len = 0;
    while ((len = in.read(buf)) != -1) {
    out.write(buf, 0, len);
    }
    }

    public void run() {
    try{
    send();
    receive();
    }finally{
    try{
    in.close();
    }catch(IOException e){
    e.printStackTrace();
    }finally{
    try {
    out.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    }}Client启动代码
    new Client("127.0.0.1",6666).run();最后还有一个小小的建议,发送和接受文件不要弄成同一个,比较容易出错
      

  2.   

    你的代码中只能读入1个文件, 传送,然后写入一个文件。并不支持多个文件的读入,和多个文件的写入。
    你只要在Server中结束一个文件时,重新new出所有流(包括一个新文件)
    在客户端中,写完第一个文件时,重新建立所有流(包括一个新输入文件),所有的socket不要动,还用原来的,也不要释放就可以。
      

  3.   

    别管怎么说 先谢谢你们两位了~~
    第一次写tcp的东西,自己确实不怎么会~~东拼西凑了这么个东西,我自己再改改,谢谢两位的回答
      

  4.   

    我的代码给你参考:
    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Date;import javax.swing.JLabel;
    import javax.swing.JTextArea;
    public class GetMessage extends Thread{
    private int i;
    String v;

    JLabel label=null;
    private JTextArea text;
    Date d=new Date();
    SimpleDateFormat matter=new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒");
    public GetMessage(int i,JTextArea text) { this.i=i;
    this.text=text;
    }

    public void run(){
    try {
    ServerSocket so = new ServerSocket(i);
    Socket s = so.accept();
    while(true){
    InputStreamReader i = new InputStreamReader(s.getInputStream());
    BufferedReader b = new BufferedReader(i);
     v= b.readLine();
      text.append(String.valueOf(matter.format(d))+"\n");
       text.append("对方说"+v+"\n");
     }
    } catch (IOException e) {
    System.out.println(e.getMessage());
    //label.setText("对方已经下线");
    text.append("对方下线了");
    }
    }
    }
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintStream;
    import java.net.Socket;
    import java.net.UnknownHostException;import javax.swing.JLabel;
    import javax.swing.JTextArea;
    import javax.swing.JTextField;
    public class SendMessage extends Thread {
    private String ip;
    private int i;
    Socket s = null;
    JLabel label=null;
    JTextField text;
    JTextArea text1;

    public SendMessage(String ip,int i,JTextArea text1) {
    // TODO Auto-generated constructor stub
    this.ip=ip;
    this.i=i;
    this.text1=text1;
      
    }


        public void run(){
        
         while(true){
    try {
     s = new Socket(ip,i);
         text1.setText("连接成功"+"\n");
     break;
    } catch (Exception e) {
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e1) {
    System.out.println("出错了。");
    }

         }
        
        }                        
        
         public  void send(String message)
         {
    try {

    PrintStream p = new PrintStream(s.getOutputStream()); p.println(message);

        
    } catch (Exception e1) {
    System.out.println("异常"+e1.getMessage());
    }
    }
          
          
    }
      

  5.   

    恩  你这个聊天软件也不错哈  头回发提问帖,谢谢各位好心人的回复
    这会仔细读了下二楼的代码~~~哥们谦虚了,很严谨的程序,受教了。
    我还想知道的是为什么我关闭bw的时候会关闭 socket而二楼的代码却不会?领悟能力有限,哪位好心人给解答下~
      

  6.   

    额,上一个问题二了~~~~二楼的代码没有关闭过 in和 out,只在最后文件传输完毕后关闭了这两个流。如果想在in和out上再包上其它的高层流该,比如说BufferedReader,BufferedWriter啥的,怎么处理?也不关闭么?会不会存在什么问题?
      

  7.   

    对于socket编成
    1、client连上后,如果是同步短连接的话,数据传输完后需要关闭is和os,同时关闭socket。
    2、如果是长连接的话,就什么都不要关。
    3、你用BufferedReader,BufferedWriter最终都是调用了socket相关的inputstream和outputStream,BufferedReader,BufferedWriter只是对这两个流进行包装,最终数据传输完成,还是要参照1、2
      

  8.   

    你在调用 BufferedReader,BufferedWriter的close方法,方法内部什么自己调用被 包装类的close方法,所以你只需要显示的调用 BufferedReader,BufferedWriter的close方法即可