我已经使用Java套接字实现了文件传输程序。在此程序中,文件是从客户端发送的,然后将其下载到服务器中。该程序几乎可以正常工作,但是问题是接收到的字节长度始终大于从客户端发送的字节长度。例如,我从客户端发送了678888589字节,但是当我在服务器上检查接收到的文件的长度时,我得到了678925260字节。因此,我在服务器端得到了不同的校验和。
这是我的代码: 客户类别:
public class Client
{
final static int ServerPort = 1234;
public static final int BUFFER_SIZE = 1024 * 50;
private static byte[] buffer;
public static void main(String args[]) throws UnknownHostException, IOException
{
Scanner scn = new Scanner(System.in);
buffer = new byte[BUFFER_SIZE];
for(int i=0;i<8;i++) {
Socket s1 = new Socket(ip, ServerPort);
DataOutputStream dos1 = new DataOutputStream(s1.getOutputStream());
SendMessage message = new SendMessage(s1, "test.mp4",dos1);
Thread t = new Thread(message);
System.out.println("Adding this client to active client list");
t.start();
}
}
}
class SendMessage implements Runnable{
String file_name;
Socket s;
public final int BUFFER_SIZE = 1024 * 50;
private byte[] buffer;
DataOutputStream dos;
public SendMessage(Socket sc,String file_name,DataOutputStream dos) {
this.file_name = file_name;
this.s=sc;
buffer = new byte[BUFFER_SIZE];
this.dos = dos;
}
@Override
public void run() {
File file = new File(file_name);
try {
sendFile(file, dos);
dos.close();
while(true) {
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
public void sendFile(File file, DataOutputStream dos) throws IOException {
byte[] buffer = new byte[BUFFER_SIZE+1];
if(dos!=null&&file.exists()&&file.isFile())
{
FileInputStream input = new FileInputStream(file);
dos.writeLong(file.length());
System.out.println(file.getAbsolutePath());
int read = 0;
int totalLength = 0;
while ((read = input.read(buffer)) != -1) {
dos.write(buffer);
totalLength +=read;
System.out.println("length "+read);
}
input.close();
System.out.println("File successfully sent! "+totalLength);
}
}
}
服务器类
// Server class
public class Server
{
// Vector to store active clients
static Vector<ClientHandler> ar = new Vector<>();
// counter for clients
static int i = 0;
public static void main(String[] args) throws IOException
{
// server is listening on port 1234
ServerSocket ss = new ServerSocket(1234);
Socket s;
// running infinite loop for getting
// client request
while (true)
{
// Accept the incoming request
s = ss.accept();
System.out.println("New client request received : " + s);
// obtain input and output streams
DataInputStream dis = new DataInputStream(s.getInputStream());
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
System.out.println("Creating a new handler for this client...");
// Create a new handler object for handling this request.
ClientHandler mtch = new ClientHandler(s,"client " + i, dis, dos);
// Create a new Thread with this object.
Thread t = new Thread(mtch);
System.out.println("Adding this client to active client list");
// add this client to active clients list
ar.add(mtch);
// start the thread.
t.start();
// increment i for new client.
// i is used for naming only, and can be replaced
// by any naming scheme
i++;
}
}
}
// ClientHandler class
class ClientHandler implements Runnable
{
Scanner scn = new Scanner(System.in);
private String name;
final DataInputStream dis;
final DataOutputStream dos;
Socket s;
boolean isloggedin;
public static final int BUFFER_SIZE = 1024*50;
private byte[] buffer;
// constructor
public ClientHandler(Socket s, String name,
DataInputStream dis, DataOutputStream dos) {
this.dis = dis;
this.dos = dos;
this.name = name;
this.s = s;
this.isloggedin=true;
buffer = new byte[BUFFER_SIZE];
}
@Override
public void run() {
String received;
BufferedOutputStream out = null;
String outputFile = "out_"+this.name+".mp4";
BufferedInputStream in = null;
try {
in = new BufferedInputStream(s.getInputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
out = new BufferedOutputStream(new FileOutputStream(outputFile));
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// while (true)
// {
try
{
long length = -1;
length = dis.readLong();
if(length!=-1)System.out.println("length "+length);
// String checkSum = dis.readUTF();
// System.out.println(checkSum);
int len=0;
long totalLength = 0;
// int len = 0;
while ((len = in.read(buffer,0,BUFFER_SIZE)) > 0) {
out.write(buffer, 0, len);
totalLength+=len;
// if(len<BUFFER_SIZE)break;
// System.out.println("length "+len);
if(len<=0)break;
}
File file = new File(outputFile);
System.out.println("total length1 "+totalLength+ " dif "+(totalLength-length));
System.out.println("output length "+file.length());
} catch (IOException e) {
e.printStackTrace();
}
}
private static String checksum(String filepath, MessageDigest md) throws IOException {
// file hashing with DigestInputStream
try (DigestInputStream dis = new DigestInputStream(new FileInputStream(filepath), md)) {
while (dis.read() != -1) ; //empty loop to clear the data
md = dis.getMessageDigest();
}
// bytes to hex
StringBuilder result = new StringBuilder();
for (byte b : md.digest()) {
result.append(String.format("%02x", b));
}
return result.toString();
}
}
如果有人能告诉我我做错了,那将是很好的。另外,如何在服务器端验证校验和。另一个问题是服务器端代码在此块中被阻塞。
while ((len = in.read(buffer,0,BUFFER_SIZE)) > 0) {
out.write(buffer, 0, len);
System.out.println("length "+len);
if(len<=0)break;
}
除非断开客户端的连接,否则无法中断循环。虽然可以正确接收文件。
致谢。
答案 0 :(得分:1)
您在客户端代码上犯了一个小错误。您正在写出完整的缓冲区,而不是从文件中读取的内容。
while ((read = input.read(buffer)) != -1) {
dos.write(buffer,0,read);
totalLength += read;
System.out.println("length " + read);
}