День добрый.
Имеется клинт-серверное приложение. Пользователь загружает файл и отправляет его в исходящий поток сокета на сервер.
Все это происходит в отдельном потоке что бы не занимать время у других процессов. (в моем случае граф. интерфейс и методы JLayer).
Java |
1
| Thread f = new Thread(new FSender (filePath, DOS)); |
|
Где:
FSender пользовательский класс (см. ниже)
String filePath - путь к файлу
DataOutputStream DOS ссылка на поток
Java |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
| import java.io.*;
//import java.nio.file.*;
import java.net.*;
/**
*
* @author sls
*/
public class FSender implements Runnable{
String pth = null;
FileInputStream input;
DataOutputStream DOS;
/**
* @return
*/
FSender (String filePath, DataOutputStream ou)
{
if (!"".equals(filePath))
pth = filePath;
else
System.out.println("Path of file equals NILL \n");
//input = in;
DOS = ou;
}
public void run()
{
this.SendFile();
}
private synchronized boolean SendFile ()
{
//String pth1 = "//home//sls//Music//Social.mp3"; // задать путь к исходному файлу
// Path testFilePath = Paths.get(pth1); //
System.out.println("Preparing " +pth + " to send on server");
try{
File file = new File(pth);
input = new FileInputStream (file); // открыть поток для считывания байт из файла
int size = (int)file.length();
byte[] buffer = new byte[size];
System.out.println("File size = "+ size+ "...");// буфер считывания
Socket socket = new Socket("127.0.0.1", 7070); // сокет с программой, которая будет заниматься приемом/передаче файлов
System.out.println("Socket ready...");
DOS = new DataOutputStream(socket.getOutputStream()); // открываем поток сокета для вывода байт в него
System.out.println("Output Stream ready...");
int count = 0;
int receivedBytes = -1;
while(true) {
count ++;
receivedBytes = input.read(buffer); // читаем файл целиком в буфер
if (receivedBytes == -1) {
break;
}
{
System.out.println(receivedBytes);
}
if (receivedBytes > 0) {
System.out.println("Writing + "+receivedBytes+ "...");
DOS.write(buffer, 0, receivedBytes); // пишем буфер в исходящий поток клиентского сокета
DOS.flush();
}
}
System.out.println("File was sent");
input.close(); // закрываем потоки
DOS.close();
socket.close();
} catch (Exception ex){
System.out.println(ex);
return false;
}
return true;
} // end of method
} // end of class |
|
Сервер создает сокет и запускает отдельный поток, в котором выполняется след. run()
Java |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| public void run() {
try {
{
int receivedBytes = 0;
System.out.println(receivedBytes + " arived ");
while((receivedBytes = Dinput.read(buffer))!=-1) {
try {
System.out.println(receivedBytes + " arived ");
if (receivedBytes == -1) {
break;
}
if (receivedBytes > 0)
{
FOS.write(buffer, 0, receivedBytes);
FOS.flush();
}
} catch (IOException ex) { }
}
} // Закрываем run |
|
Проблема:
Злощастный планировщик потоков для меня загадка, а положение вещей усугубляет работа с потоками сокетов, которая для меня не менее загадочна.
Принцип работы с "слушателями" потоков сокетов освоил на примере чата.
Java |
1
2
3
4
5
6
7
8
9
10
11
| public void run() {
String message;
try {
while ((message = reader.readLine()) != null) {
System.out.println("Hello from T stream");
System.out.println("read " + message);
tellEveryone(message);
} // Закрываем while
} catch(Exception ex) {ex.printStackTrace();}
} // Закрываем run |
|
Попытался применить что-то такое же к файлам.
Java |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
| class ClientHandlerFiles implements Runnable {
int size = 23584640;
byte[] buffer = new byte[size];
BufferedInputStream BIS;
Socket sockF;
String pth2 = "//home//sls//Music//tmp_file.mp3";
FileOutputStream FOS;
DataInputStream Dinput;
public ClientHandlerFiles(Socket clientSocketFiles) {
try {
FOS = new FileOutputStream(pth2);
sockF = clientSocketFiles;
Dinput = new DataInputStream(sockF.getInputStream());
} catch(Exception ex) {}
} // Закрываем конструктор
@Override
public void run() {
try {
{
int receivedBytes = 0;
System.out.println(receivedBytes + " arived ");
while((receivedBytes = Dinput.read(buffer))!=-1) {
try {
System.out.println(receivedBytes + " arived ");
if (receivedBytes == -1) {
break;
}
if (receivedBytes > 0)
{
FOS.write(buffer, 0, receivedBytes);
FOS.flush();
}
} catch (IOException ex) { }
}
} // Закрываем run
}
catch (IOException ex) { }
} |
|
Но вот загвоздка, при отправке клиентом файла, сервер в упор не замечает входящей информации. Поток(thread), который должен считать и сохранить у себя на месте файл, запускается лишь единожды при подключении клиентов. Получается загрузив файл на стороне клиента, что бы файл дошел до сервер, приходится перезапускать приложения клиента и тогда, по непонятным мне причине, происходит считывание файла. Что же читать и делать?