2013-04-17 2 views
1

Я разработал многопоточный сервер, который работает хорошо! , но теперь я хочу, чтобы он отправил в первый раз, когда клиент соединяет строку, а затем продолжит с тем же регулярным процессом, получая строку и отправляя файл! вот мой код для сервераЯ хочу отправить строку с многопоточного сервера только при подключении клиента

import java.io.*; 
import java.net.*; 
import java.nio.ByteBuffer; 
import java.util.Scanner; 

class TCPServer { 
    public static void main(String argv[]) throws Exception { 

     System.out.println("Welcome to the stream Server"); 
System.out.println("listening to Clients"); 
     ServerSocket welcomeSocket = new ServerSocket(3248); 
     while (true) { 
      Socket connectionSocket = welcomeSocket.accept(); 
      if (connectionSocket != null) { 
       Client client = new Client(connectionSocket); 
       client.start(); 

      } 
     } 
    } 
} 

class Client extends Thread { 
    private Socket connectionSocket; 


    public Client(Socket c) throws IOException { 
     connectionSocket = c; 
    } 

    public void run() { 

     String path = "C:/pao/new2/"; 

     File folder = new File(path); 
     File[] listOfFiles = folder.listFiles(); 


     try { 

      String fileToSendStr = readFile(); 
      File fileToSend = null; 
      for (File f : listOfFiles) 

      { 

       if (f.getName().equals(fileToSendStr)) { 
        fileToSend = f; 
        break; 
       } 
      } 
      System.out.println("Connecting to Client to recieve the part " +fileToSendStr); 
      if (fileToSend == null) { 

      } 
      System.out.println("Sending the chunk to Client"); 
      long length = fileToSend.length(); 
      byte [] longBytes = new byte[8]; 
      ByteBuffer bbuffer = ByteBuffer.wrap(longBytes); 
      bbuffer.putLong(length); 
      connectionSocket.getOutputStream().write(longBytes); 

      BufferedOutputStream bout = new BufferedOutputStream(connectionSocket.getOutputStream()); 
      BufferedInputStream bain = new BufferedInputStream(new FileInputStream(fileToSend)); 

      byte buffer [] = new byte [1024]; 
      int i = 0; 
      while((i = bain.read(buffer, 0, 1024)) >= 0){ 
       bout.write(buffer, 0, i); 

      } 
      System.out.println("chunk sended"); 
      bout.close(); 
      bain.close(); 


     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

    } 

    private String readFile() throws IOException { 

     BufferedReader r = new BufferedReader(new InputStreamReader(
       connectionSocket.getInputStream())); 
     return r.readLine(); 

    } 
} 

часть клиента, который хочет сделать соединение отличается от той части, что делает это соединение. только хочу получить строку в первый раз, а затем эта часть больше не доступна!

ответ

0

ServerSocket.accept() - метод блокировки. Он не будет возвращаться, если соединение не было установлено или не был установлен тайм-аут (ранее установленный).

Поместите код сервера в отдельном потоке инстанциации клиентов, или поставить таймаут для сокета:

ServerSocket welcomeSocket = new ServerSocket(3248); 
welcomeSocket.setSoTimeout(2000); // waits 2 seconds for a client. 
while (true) { 
    (new Thread(new Runnable() { 
     public void run() { 
      Socket connectionSocket = welcomeSocket.accept(); 
      if (connectionSocket != null) { 
       Client client = new Client(connectionSocket); 
       client.start(); 
      } 
      } 
     })).start(); 
     try { 
      welcomeSocket.accept(); 
     } catch(Exception e) { 
      //socket timeout. 
     } 
} 
+0

, набрав тайм-аут, чтобы welcomeSocket, что я заработаю! выйти за пределы петли? но тогда мне нужно будет снова запустить сервер! – Cbour

+0

Да, это вызовет исключение. Вам нужно поймать его. Помимо этого, вы должны действительно отделить поток, который вы принимаете, от клиентов потока, созданного клиентами. –

0

я не уверен, если я понимаю, это хорошо, но вы говорите, что в настоящее время сервер работает хорошо и может обслуживать клиентов. Вы хотите знать, уже ли клиент уже подключен? Связь между вашим сервером и клиентом охватывает несколько соединений?

Для этого потребуется концептуальное мышление. Если бы вы были на земле HTTP, это означало бы какую-то концепцию сеанса и/или cookie. С помощью файла cookie сервер может хранить информацию на стороне клиента (в последний раз клиент подключался, какое-то состояние). С идентификатором сеанса вы можете отслеживать, в каком состоянии вы находитесь во время общения с клиентом.

В вашем случае вам может потребоваться разработать очень простой протокол уровня приложения (вверху сетевого стека ISO/OSI). Так, например, после установления соединения клиент отправит байт на сервер, на котором будет проходить этап обмена информацией, тогда сервер будет реагировать в соответствии с этим. В конце сообщения этот параметр состояния будет обновлен, пересмотрен.

Помогло ли это?

+0

Посмотрите, как клиент идет сейчас и отправляет, поскольку вы можете увидеть строку, а затем получить файл! я хочу, чтобы клиент, когда подключается, не подключается к отправке, а подключается для получения строки только в первый раз! после этого подключитесь и сделайте то, что нужно! – Cbour

+0

Я думаю, что это все еще концептуальная дилемма. Как сервер должен знать, что определенный клиент только хочет читать? Он должен знать откуда-то. Где-то историю/этап предыдущего сеанса связи с клиентом следует сохранить и изучить. Насколько я понимаю. Помимо этих сокетов TCP - это дуплексные каналы связи. Именно на клиенте и на сервере сам решать и обсуждать, когда и кто будет отправлять и получать данные через эту «трубу». –