#java #sockets
#java #сокеты
Вопрос:
вот небольшой код, который я написал. Этот следующий класс ожидает подключения и создает новый поток после его получения:
ServerSocket serverSocket = null;
ExecutorService serv = Executors.newCachedThreadPool();
serv.execute(new UserThread());
try {
serverSocket = new ServerSocket(FMDataManager.getPort());
serverSocket.setSoTimeout(0);
while (_listening){
System.out.println("Listening on port " FMDataManager.getPort());
System.out.println("Waiting for connections.");
serv.execute(new UploadThread(serverSocket.accept()));
}
} catch (IOException e) {
System.err.println("Could not listen on port: " FMDataManager.getPort() ".");
System.exit(-1);
}
как вы можете видеть, я использую метод ServerSocket.accept() для ожидания соединения.
Поток действительно создан, но он не будет запускаться. Я поместил небольшое «созданный поток» в его конструктор и другое сообщение «запуск потока» в run (), но я получил только первое сообщение. После этого он ничего не сделал, я даже не получил «созданный поток».
Пожалуйста, есть идеи?
Я добавил реализацию UploadThread, которую пытаюсь запустить, может быть, это поможет
public class UploadThread extends Thread{
Socket _socket;
public UploadThread(Socket socket) {
super("UserThread");
_socket = socket;
}
public void run(Socket socket) {
System.out.println("entred upload thread");
DataOutputStream out = null;
DataInputStream in = null;
try {
out = new DataOutputStream(_socket.getOutputStream());
in = new DataInputStream(_socket.getInputStream());
FileMessage inputMessage;
SendFile outputMessage;
inputMessage = (FileMessage) CommandEnum.readMessage(in);
System.out.println("F: " inputMessage.getCaption());
File file = null;
Iterator<File> itr = FMDataManager.getFiles().iterator();
while (itr.hasNext()){
File temp = itr.next();
if (temp.getName().equals(inputMessage.getFile()))
file = temp;
}
outputMessage = new SendFile(file);
outputMessage.send(out);
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
_socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Комментарии:
1. Есть ли шанс, что мы сможем увидеть вашу
UploadThread
реализацию`? особенно сигнатура класса, конструктор и (начало) метода запуска, включая сигнатуру метода2. похоже, вы неправильно переопределяете
run()
.
Ответ №1:
Попробуйте serv.submit
вместо serv.execute
.
Редактировать
Похоже, что UploadThread
неправильно переопределяется run()
. При этом объявление вашего метода run должно выглядеть следующим образом:
@Override
public void run(){
//do stuff
}
Нет необходимости передавать socket
в качестве аргумента.
Ответ №2:
Как указано в комментарии sthupahsmaht, ваша UploadThread
реализация неверна. Сигнатура для run()
метода является public void run()
. В настоящее время вы создаете новый метод с сигнатурой public void run(Socket)
. Поскольку run()
не принимает никаких аргументов, вы должны передать все параметры через конструктор или установщики.
Есть две рекомендации, которые помогут вам избежать подобных ошибок в будущем:
- Всякий раз, когда вы реализуете или переопределяете метод, комментируйте его с помощью
@Override
. Если вы создаете новый метод с помощью@Override
, компилятор выдает сообщение об ошибке. - Не расширяйте,
Thread
но реализуйтеRunnable
.Thread
имеет реализацию по умолчанию дляrun()
, которая ничего не делает. Это то, что происходит с вашим кодом в данный момент.
Комментарии:
1. Хорошо, как я мог пропустить, что на этот вопрос уже дан ответ? Я думаю, что я не перезагружал вкладку своего браузера и увидел кэшированную версию со вчерашнего дня. Я оставляю ответ как дополнение к ответу sthupahsmaht.
Ответ №3:
Не видя части кода, которая фактически создает поток, я предполагаю, что вы НЕ вызываете метод ‘start()’ для объекта thread.
Должно быть что-то вроде этого:
Thread thr = new Thread(new Runnable() { void run() { /* do stuff */ }) ;
thr.start() // GO!
Комментарии:
1. Это то, что я использую для вызова потока: serv.execute(new UploadThread(ServerSocket.accept())); Он должен создать его и запустить
2. является ли UploadThead() одной из ваших конструкций или частью используемого вами API?
3. служба ExecutorService должна запустить отправленный поток в какой-то момент в будущем
4. Почему за это проголосовали?
ExecutorService
это концепция более высокого уровня, чемThread
которая беретRunnable
и делает то, что, по ее мнению, она должна делать. Нет необходимости создавать поток и запускать его.5. итак, я все еще не понимаю, что мне делать. идеи?