调了一下午了,长度死活穿不过去
服务器端:import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Man1 extends JFrame {
JLabel lab = null;
JTextField jf = null;
JButton btn = null;
JButton btnSend = null;
File f1 = null;

FileInputStream fis = null;
BufferedInputStream bis = null;

BufferedOutputStream bos =null;

Socket sk = null;
ServerSocket ssk = null;
public Man1() {
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setBounds(100, 100, 500,80);
this.setTitle("简单的文件传输程序");
this.setResizable(false);
lab = new JLabel("路径:");
jf  = new JTextField(20);
btn = new JButton ("选择要传送的文件");
btnSend = new JButton ("发送");
JPanel pan =(JPanel) this.getContentPane();
pan.setLayout(new FlowLayout());
pan.add(lab);
pan.add(jf);
pan.add(btn);
pan.add(btnSend);
this.setVisible(true);
try {
ssk = new ServerSocket(7778);
System.out.println("服务器正在监听....");
sk = ssk.accept();
System.out.println("有客户端连接上....");
} catch (IOException e1) {
e1.printStackTrace();
}
//消息处理
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFileChooser jfc = new JFileChooser();
int flag = jfc.showOpenDialog(null);
if(flag==jfc.APPROVE_OPTION){
f1 = jfc.getSelectedFile();
String path = f1.getAbsolutePath();
jf.setText(path);
}
}
});
btnSend.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {

//发送文件
sendFile();
}
});
}
public void  sendFile(){
String path = f1.getAbsolutePath();
String name = f1.getName()+";";
String  len = f1.length()+""; try {

fis = new FileInputStream(new File(path));
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(sk.getOutputStream()); bos.write(name.getBytes());
bos.flush();
// ?????????????此处len穿不过去
bos.write((len+";").getBytes());
bos.flush();

byte [] length = new byte[Integer.parseInt(len)];
int i=0;
while((i=fis.read(length))!=-1){
bos.write(length);
}
bos.flush();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try{
if(sk!=null){
sk.close();
}
if(ssk!=null){
ssk.close();
}
if(fis!=null){
fis.close();
}
if(bos!=null){
bos.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new Man1();
}}
============================================================================
============================================================================
客户端:import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Client1 extends JFrame {

Socket sk = null;

// FileInputStream fis = null;
BufferedInputStream bis = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;

JPanel pan1 = null;//中
JPanel pan2 = null;//南
JPanel pan3 = null;//北
JLabel name = null;
JLabel length=null;
JTextField jfname =null;
JTextField jfleng =null;
JButton jbtSave = null;
JLabel info = null; public Client1() {
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setBounds(100, 100, 500, 200);
this.setTitle("文件传输客户端...");
JPanel pan = (JPanel)this.getContentPane();
pan1 = new JPanel();
pan1.setLayout(new GridLayout(2, 2));
pan2 = new JPanel();
pan3 = new JPanel();
info = new JLabel("接受来自服务器端传输来的文件···");
pan.add(pan1);
pan.add(pan2,BorderLayout.SOUTH);
pan.add(pan3,BorderLayout.NORTH);
pan3.add(info);

name = new JLabel("文件名:");
pan1.add(name);
jfname = new JTextField(20);
jfname.setEditable(false);
pan1.add(jfname);
length = new JLabel("文件长度:");
pan1.add(length);
jfleng = new JTextField(20);
jfleng.setEditable(false);
pan1.add(jfleng);

jbtSave = new JButton("接收文件");
pan2.add(jbtSave);

this.setVisible(true);
try {
sk = new Socket("127.0.0.1", 7778);


} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}


jbtSave.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//保存得到的文件;
saveFile();
}
});
}
public void saveFile(){
try {
bis = new BufferedInputStream(sk.getInputStream());
byte [] name = new byte[50];
bis.read(name);

byte [] len = new byte[50];
bis.read(len);

String filename = new String(name).split(";")[0];
String filelen = new String(len).split(";")[0];
System.out.println("kkkkkkk= "+filelen); jfname.setText(filename);
jfleng.setText(filelen);

byte [] text = new byte[Integer.parseInt(filelen)];
fos = new FileOutputStream(new File("D:/"+name.toString()));
bos = new BufferedOutputStream(fos);
int i=-1;
while((i=bis.read(text))!=-1){
bos.write(text);
} } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try{
if(sk!=null){
sk.close();
}
if(bos!=null){
bos.close();
}
if(fos!=null){
fos.close();
}
if(bis!=null){
bis.close();
}
}catch(Exception e){
e.printStackTrace();
}
}

// JFileChooser jfc = new JFileChooser();
// int flag = jfc.showSaveDialog(null);
//
//
}
public static void main(String[] args) {
new Client1(); }}

解决方案 »

  1.   

    初学者常见错误,没有将写跟读进行良好匹配。byte [] name = new byte[50];
    bis.read(name);一口气读50个字节,全给你读到name里面去了
    建议用封装的更好的方式:
    1、写的时候,不要用“分号”做分割符,而是用"\n"做分割符:
    String name = f1.getName()+"\n";
    String len = f1.length()+"\n";
    bos.write(name.getBytes());
    bos.write(len.getBytes());
    bos.flush();
    2、读的时候,用可以自动处理“行”的类:
    BufferedReader br = new BufferedReader(InputStreamReader(sk.getInputStream()));
    String name = br.readLine();
    String len = br.readLine();
      

  2.   

    接收方不对。
    不应该每次读50字节,应该readLine一次读出来为字符串,然后对该字符串split(";")即可。
    filename为[0]号元素,filelen为[1]号元素。
      

  3.   

    你是怎么调试知道长度没有传过去?
    其实传过去了,是你的取值方式有问题。
    我帮你改好了,就改了saveFile方法就好,改了哪你自己看下。
    注:byte[] data = new byte[1024];
    我设置文件长度最大1K,如果想要动态根据实际文件长度的话,得写其他逻辑代码。
    public void saveFile() {
    try {
    bis = new BufferedInputStream(sk.getInputStream());
    byte[] data = new byte[1024];
    int len=bis.read(data);
    String dataStr=new String(data,0,len);
    String[] datas=dataStr.split(";");
    String filename = datas[0];
    String filelen = datas[1];
    System.out.println("kkkkkkk= " + filelen); jfname.setText(filename);
    jfleng.setText(filelen); fos = new FileOutputStream(new File("D:/" + filename.toString()));
    PrintWriter pw=new PrintWriter(fos);
    pw.println(datas[2]);
    pw.close();
    } catch (Exception e) {
    e.printStackTrace();
    } finally {
    try {
    if (sk != null) {
    sk.close();
    }
    if (bos != null) {
    bos.close();
    }
    if (fos != null) {
    fos.close();
    }
    if (bis != null) {
    bis.close();
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }
      

  4.   

    貌似是因为发送流的原因,虽然你是分别发送文件名和文件长度的,但因为你是写在流里面的,流就读取你所给空间的长度,你在Client1中读取name用了50个字节,所以在读取文件名的同时把文件长度和一部分文件数据都读进来了,然后后面就肯定出错了你要实现这个功能,就要改一下发送那部分的代码,在发送文件名和文件长度前前先定义一个50字节的缓冲区,然后将你需要的信息复制到那个50字节的缓冲区里面去,之后发送这50个字节的缓冲区,这样发送和接受才能对应起来
    byte[] buffer = new byte[50];
    System.arraycopy(name.getBytes(), 0, buffer, 0, name.getBytes().length);
    bos.write(buffer);
    bos.flush();
    // ?????????????此处len穿不过去
    buffer = new byte[50];
    System.arraycopy((len + ";").getBytes(), 0, buffer, 0, (len + ":").length());
    bos.write(buffer);
    bos.flush();