我正在尝试从客户端向服务器发送文件。以下是我尝试过的代码。但有时,传输过程中会丢失数据包。我不确定我错在哪里。
服务器端代码:
public static void ReadAndWrite(byte[] aByte, Socket clientSocket,
InputStream inputStream, String fileOutput)
throws FileNotFoundException, IOException {
int bytesRead;
FileOutputStream fileOutputStream = null;
BufferedOutputStream bufferedOutputStream = null;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try
{
fileOutputStream = new FileOutputStream( fileOutput );
bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
bytesRead = inputStream.read(aByte, 0, aByte.length);
System.out.println("The length is "+bytesRead);
int count = 0;
do {
count++;
byteArrayOutputStream.write(aByte);
bytesRead = inputStream.read(aByte);
} while (bytesRead != -1);
System.out.println("The count is "+count);
System.out.println("The length is "+byteArrayOutputStream.size());
bufferedOutputStream.write(byteArrayOutputStream.toByteArray());
bufferedOutputStream.flush();
bufferedOutputStream.close();
clientSocket.close();
}
catch(Exception ex)
{
Logger.writeLog(ex,Listen.class.getName(), LogType.EXCEPTION);
throw ex;
}
客户端代码:
public void readByteArrayAndWriteToClientSocket(
Socket connectionSocket, BufferedOutputStream outToClient, String fileToSend ) throws Exception
{
try{
if (outToClient != null)
{
File myFile = new File(fileToSend);
System.out.println(myFile.length());
byte[] byteArray = new byte[(int) myFile.length()];
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(myFile);
} catch (IOException ex) {
Logger.writeLog(ex, FileUtility.class.getName(), LogType.EXCEPTION);
throw ex;
}
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
try {
bufferedInputStream.read(byteArray, 0, byteArray.length);
outToClient.write(byteArray, 0, byteArray.length);
outToClient.flush();
outToClient.close();
connectionSocket.close();
return;
} catch (IOException ex) {
Logger.writeLog(ex, FileUtility.class.getName(), LogType.EXCEPTION);
throw ex;
}
}
}catch (Exception e) {
Logger.writeLog(e, getClass().getName(), LogType.EXCEPTION);
throw e;
}
}
答案 0 :(得分:4)
没有“数据包丢失”,只是代码中的错误。
在Java中复制流的规范方法如下:
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
如果您事先知道字节数且发送方必须在转移后保持连接打开,它将变为:
while (total < expected && (count = in.read(buffer, 0, expected-total > buffer.length ? buffer.length : (int)(expected-total))) > 0)
{
out.write(buffer, 0, count);
total += count;
}
忘记所有ByteArrayInput/OutputStreams
和额外的副本。只需从文件中读取并发送到套接字,或从套接字读取并写入文件。
答案 1 :(得分:3)
套接字读取方法将在它获取您要求的所有字节时返回,或者,当它停止从网络接收数据时返回。
由于传输经常在任何真实网络中被中断,因此您需要继续发出读取调用,直到您拥有所需的字节数。
你需要这样的代码:
char [] buffer = new char[1024];
int expect = 1000;
int sofar = 0;
int chars_read;
try
{
while((chars_read = from_server.read(buffer[sofar])) != -1)
{
sofar = sofar + chars_read;
if (sofar >= expected) break;
}
}
catch(IOException e)
{
to_user.println(e);
}