我试图用很多方式解决问题,但没有成功,我也在此论坛中查找了信息,但结果相同,所以我们现在就去。Java套接字同步行为
我实际上在做一个服务器守护进程,它接受客户端请求,然后它(服务器)传输包含在特定文件夹中的所有文件。我将发布sendFileData(在服务器上)和receiveFileData(在客户端上)的代码。
服务器使用:
public static void sendFileData(File file, Socket socket) throws FileNotFoundException, IOException, SocketException {
byte[] auxiliar = new byte[8192];
byte[] mybytearray = new byte[(int) file.length()];
int longitud = mybytearray.length;
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
bis.read(mybytearray, 0, longitud);
DataOutputStream os = new DataOutputStream(socket.getOutputStream());
int paquetes = longitud/8187;
int resto = longitud % 8187;
int i = 0;
while(i<paquetes){//The length goes on the first 4 bytes and the 5th tells if there are more packets to send (8192 bytes or less).
byte[] bytes = ByteBuffer.allocate(4).putInt(8187).array();
auxiliar[0] = bytes[0];
auxiliar[1] = bytes[1];
auxiliar[2] = bytes[2];
auxiliar[3] = bytes[3];
auxiliar[4] = 1;
for(int j = 5; j < 8192; j++){
auxiliar[j] = mybytearray[i*8187+(j-5)];
}
os.write(auxiliar, 0, 8192);
i+=1;
}
if(resto > 0){
byte[] bytes = ByteBuffer.allocate(4).putInt(resto).array();
auxiliar[0] = bytes[0];
auxiliar[1] = bytes[1];
auxiliar[2] = bytes[2];
auxiliar[3] = bytes[3];
auxiliar[4] = 0;
for(int j = 5; j < resto+5; j++){
auxiliar[j] = mybytearray[i*8187+(j-5)];
}
os.write(auxiliar, 0, resto+5);
}
os.flush();
}
而在客户端:
public static void receiveFileData(String nombreFichero, Socket s) throws IOException{
File monitored = new File(nombreFichero);
if(monitored.exists() == false){
monitored.createNewFile();
}
byte[] mybytearray;
DataInputStream is = new DataInputStream(s.getInputStream());
FileOutputStream fos = new FileOutputStream(monitored);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int bytesRead = 0;
int hasNext = 1;
do {
bytesRead = is.readInt();//Leo longitud
try {
Thread.sleep(1);// HERE!!!!
} catch (InterruptedException e) {
}
// System.out.println("Bytes read "+bytesRead);
if(bytesRead <= 8187 && bytesRead > 0){
// System.out.println("Bytes leídos "+bytesRead);
hasNext = is.readByte();//Leo si hay más datos por enviar
mybytearray = new byte[bytesRead];
is.read(mybytearray);
if(monitored.exists()){
synchronized(monitored){
bos.write(mybytearray, 0, mybytearray.length);
}
}
mybytearray = null;
}else{
System.out.println("Fuera de rango "+bytesRead);
}
}while(hasNext == 1);
bos.close();
mybytearray = null;
System.out.println("Fichero recibido: "+monitored.getAbsolutePath());
}
在receiveFileData代码,如果我不把了Thread.sleep(1)或System.out的.println()或任何需要时间执行的用户,我没有以正确的方式在客户端上接收数据,因为readInt()会返回一个非常大的随机数或正数(这意味着Heap内存不足或其他异常) 。
确定这是关于同步,但我认为这两种方法之间的传输模式是正确的(也许客户端太慢,服务器速度太快)。
发生了什么?因为我不想放置Thread.sleep,所以我认为这不是很好的编程。
非常感谢!
有多少个不同的线程可能调用receiveFileData()? sendFileData()同样的问题...另外,如果你只是在做一个文件 - >文件传输...为什么甚至混淆了除字节[]以外的任何东西?您需要在数据加载之前使用一个int来告诉另一方需要多少字节,但除此之外,只需发送原始字节! – claymore1977
服务器只有一个正在侦听新连接的线程(accept())。当客户端尝试连接到服务器时,服务器会创建一个新的线程,该线程将分别管理客户端和服务器之间的数据流,然后继续监听。客户端只有一个线程。我想我试图发送完整的缓冲区文件的所有字节,但我认为这崩溃了(我必须检查,因为我现在不在家)。感谢您的回复 – cabreracanal
这段代码将整个文件从一个地方传输到另一个地方吗? – claymore1977