Я пытался решить проблему разными способами, но безуспешно, и я также искал информацию на этом форуме, но с теми же результатами, поэтому здесь мы идем.Поведение синхронизации сокета Java
Я фактически делаю демон сервера, который принимает запросы клиентов, а затем он (сервер) передает все файлы, содержащиеся в определенной папке. Я собираюсь опубликовать код sendFileData (на сервере) и getFileData (на клиенте).
Сервер использует:
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() возвращает очень высокое число случайным образом отрицательным или положительным (что подразумевает нехватку памяти и другие исключения) ,
Уверен, что это что-то о синхронизации, но я думаю, что схема переноса между двумя методами правильная (возможно, клиент слишком медленный и сервер слишком быстро).
Что происходит ??? Потому что я не хочу ставить Thread.sleep, я думаю, это нехорошее программирование.
Большое вам спасибо!
Сколько различных потоков потенциально может вызвать getFileData()? Тот же вопрос для sendFileData() ... Кроме того, если вы просто делаете File -> File transfer ... почему даже возиться с чем-либо, кроме байта []? Вам понадобится один int перед загрузкой данных, чтобы сообщить другой стороне, сколько байтов ожидать, но кроме этого просто отправьте сырые байты! – claymore1977
На сервере есть только один поток, который слушает новые подключения (accept()). Когда клиент пытается подключиться к серверу, сервер создает новый поток, который будет управлять отдельно потоками данных между клиентом и сервером, и после этого он продолжает слушать. Клиентская сторона имеет только один поток. Я думаю, что я пытался отправить полный буфер со всеми байтами файла, но я думаю, что это разбилось (я должен проверить, потому что меня сейчас нет дома). Спасибо за ваш ответ – cabreracanal
И этот код передает полный файл, неизменный, из одного места в другое? – claymore1977