我写啦一个极其简单的java文件传输程序
但是我测试的时候发现,
接收到的数据包个数总是大于或等于发出的数据包个数!
但是接收的文件却没有出错!
不知道什么原因?!
大家帮我看看,我谢谢啦!!
程序如下:
server.java//用来发送文件
package base;
import java.io.*;
import java.net.*;import javax.swing.JFileChooser;
public class server extends Thread{
public static String check_ok="OK",check_fail="NO";
private ServerSocket data;//本地SERVER_SOCKET
private Socket data_socket;
private OutputStream out_data;
/*************************************************************
 * 
 */
private FileInputStream send_file;
private JFileChooser get_o_f;
int count;


public server()
{
SEND_GUI.message.setText(" ");
SEND_GUI.reflush_text_carepoint();
try{
data=new ServerSocket(64000);
}
catch(Exception e)
{
SEND_GUI.add_text_message("server init failed! \n");
try
{
data.close();
}
catch(Exception e1){}
}
SEND_GUI.reflush_text_carepoint();
}

private void wait_be_conected()
{
try{
data_socket=data.accept();
SEND_GUI.add_text_message("server: "+data_socket+"\n");
SEND_GUI.reflush_text_carepoint();
out_data = new DataOutputStream(
new BufferedOutputStream
(data_socket.getOutputStream()));
}catch(Exception e){}
}

public boolean get_open_file()
{
int action_result=JFileChooser.CANCEL_OPTION;
File opened_file;
get_o_f = new JFileChooser();
action_result = get_o_f.showOpenDialog(SEND_GUI.main_frame);
opened_file = get_o_f.getSelectedFile();
if(opened_file!=null&&action_result==JFileChooser.APPROVE_OPTION)
try{
send_file = new  FileInputStream(opened_file);
}catch(Exception e){}
else if(action_result==JFileChooser.APPROVE_OPTION){}
SEND_GUI.add_text_message("send : "+opened_file.getAbsolutePath()+"\n");
SEND_GUI.reflush_text_carepoint();
if(send_file!=null)return true;
else return false;
}
public void run()
{
byte[] buf = new byte[65536],temp=buf.clone();
try{
 wait_be_conected();
 buf=temp;
 int num=send_file.read(buf);
 while(num!=(-1))
{
if(num<65536)
 out_data.write(buf,0,num);
 else out_data.write(buf);
SEND_GUI.add_text_message("数据"+count+"发出完成!"+"\n");
SEND_GUI.add_text_message("数据本地MD5:"+MD5_TEST.MD5Encode(buf)+"\n");
 out_data.flush();
 num=send_file.read(buf);
 count++;
 SEND_GUI.reflush_text_carepoint();
}
 SEND_GUI.message.append("传输完毕!\n");
 SEND_GUI.reflush_text_carepoint();
}catch(Exception e1)
{
SEND_GUI.add_text_message(e1.toString()+"\n");
SEND_GUI.reflush_text_carepoint();
}
 finally
 {
 try{
send_file.close();
  data_socket.close();
  data.close();
  }catch(Exception ee){}
 }

}
/*************************************************************/
   }
//////////////////////////////////////////////////////////////////////////////////////////////////
client.java//接收文件
///////////////////////////////////////////////////////////////////////////////////////////////////
package base;
import java.io.*;
import java.net.*;
import javax.swing.JFileChooser;
public class client extends Thread{
private Socket data_socket;
private InputStream in_data;
private RandomAccessFile reciv_file=null;
private JFileChooser get_s_f;
int count;
public void initclient()
{
try{
 data_socket = new Socket(InetAddress.getByName(null),64000);
 SEND_GUI.add_text_message("data : "+data_socket+"\n");
}catch(Exception e){}
SEND_GUI.reflush_text_carepoint();
} private void init_Stream()
{
try{
in_data = new DataInputStream(
new BufferedInputStream
(data_socket.getInputStream()));
}catch(Exception e){}
}

public boolean get_save_file()
{
int action_result=JFileChooser.CANCEL_OPTION;
File save_file;
get_s_f = new JFileChooser();
action_result = get_s_f.showSaveDialog(SEND_GUI.main_frame);
save_file = get_s_f.getSelectedFile();
if(save_file!=null&&action_result==JFileChooser.APPROVE_OPTION)
try{
SEND_GUI.add_text_message("save : "+save_file.getAbsolutePath()+"\n");
reciv_file = new  RandomAccessFile(save_file,"rw");
}catch(Exception e){}
else if(action_result==JFileChooser.APPROVE_OPTION){}
SEND_GUI.reflush_text_carepoint();
if(reciv_file!=null)return true;
else return false;
}
public void run()
{
byte[] buf = new byte[65536];
if(data_socket!=null)
{
init_Stream();
try{
int num=-100;
while(true)
{
num=in_data.read(buf);
if(num==(-1))break;
SEND_GUI.add_text_message("数据"+count+"读取完成!"+"\n");//添加文本到文本框
SEND_GUI.add_text_message("数据本地MD5:"+MD5_TEST.MD5Encode(buf)+"\n");
if(num<65536)
reciv_file.write(buf,0,num);
else reciv_file.write(buf);
  count++;
SEND_GUI.reflush_text_carepoint();
}
SEND_GUI.add_text_message("传输完成!\n");
SEND_GUI.reflush_text_carepoint();
}catch(Exception e)
{

}
 finally{try{
 reciv_file.close();
 data_socket.close();
 }catch(Exception ee){}
 }
} else 
 {
  SEND_GUI.add_text_message("save无效!"+"\n");
SEND_GUI.reflush_text_carepoint();
 }
}

}
//////////////////////////////////////////////////////////////////////////////////////////////////////
其他的用户界面和测试类太长就不发啦!

解决方案 »

  1.   

    难道是我服务器端的while循环一次,但是tcp底层却可能发送几次?
    但是按照我客户端的循环来看,没执行一次如果接收导数据的话,就会写入文件,
    从这点来看,在程序逻辑上看应该得到错误的文件---结果却不是!
    我疑惑的就是这个!
    tcp难道只能保证数据到达,不能保证正确?
      

  2.   

    不知道这个是否与IP报文的最大长度有关系,一个IP报文的最大长度是65535,你所用的65536笔最大报文长度还大,这还没有算IP报文控制字段的负载先按照老紫竹所说得试试。
      

  3.   

    我改为1024后,再试,果然没有多出来!
    但是我改为2048再试,客户端有多出两个包来?
    按您所说的“一个IP报文的最大长度是65535”我的2048没有大过啊!
    为什么还会多出两个包呢?我对一个文件进行测试后,
    仔细分析输出的测试文本,发现:服务器端有连续的两个包(server的30和31号),
    应该是被分成连续的四个包(client30,31,32,33号)之后的
    数据包对得上,(就是server 包第a号(a>31)对应client 包的 a+2号)这是为什么呢?
      

  4.   

    是不大,但是给你的协议有关系,你用sniffer或Wireshark抓一下包看看
      

  5.   

    我用ethereal抓包,但是没抓到数据,设置监听接口是:Realtek RTL8139/810x Family Fast Ethernet NIC
    抓取本地互传的数据包要怎样设置?
    如果拔掉网线
    能不能抓到数据包
    ip地址如何设置
      

  6.   

    ip地址你就设置成你本机的ip地址,同时过滤一下就行
      

  7.   

    如果拔掉网线 ,可以只要你的网卡是好的就行,client和server在同一台机子上