2011-12-23 4 views
2

У меня есть программа Java, которая отражает соединение с клиентского сервера на удаленный сервер. Зеркало отправляет данные на поиск, но не получает. Почему я не могу понять, почему. Вот мой код:Сокет зеркало посылает, но не принимает

Socket client = new Socket("127.0.0.1", 42001); 
System.out.println("Connected to client!"); 
Socket server = new Socket(serverAddress, serverPort); 
System.out.println("Connected to server!"); 

BufferedReader clientin = new BufferedReader(new InputStreamReader(client.getInputStream())); 
BufferedWriter scratchout = new BufferedWriter(new OutputStreamWriter(client.getOutputStream())); 

BufferedReader serverin = new BufferedReader(new InputStreamReader(server.getInputStream())); 
BufferedWriter serverout = new BufferedWriter(new OutputStreamWriter(server.getOutputStream())); 

int i; 
boolean serverNeedsFlush = false; 
boolean clientNeedsFlush = false; 
while (true) 
{ 
    while (clientin.ready()) 
    { 
     i = clientin.read(); 
     serverout.write(i); 
     serverNeedsFlush = true; 
    } 
    if(serverNeedsFlush) 
    { 
     serverout.flush(); 
     serverNeedsFlush = false; 
    } 
    while (serverin.ready()) 
    { 
     i = serverin.read(); 
     System.out.print((char)i); 
     scratchout.write(i); 
     clientNeedsFlush = true; 
    } 
    if(clientNeedsFlush) 
    { 
     scratchout.flush(); 
     clientNeedsFlush = false; 
    } 
} 
+0

Если вы используете два потока, вам не нужно будет ждать или читать строки вообще. Просто скопируйте данные по мере их получения. –

ответ

1

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

Как и другие плакаты, вы должны использовать потоки для этого. Это облегчит жизнь. Затем вы можете использовать потоки, чтобы сделать базовый вход для копирования потока, как показано ниже.

public static void streamCopy(InputStream in, OutputStream out) 
     throws IOException{ 

     byte[] data = new byte[1024]; 
     int length; 
     do{ 
      length = in.read(data); 
      if(length > 0){ 
       out.write(data, 0, length); 
       out.flush(); 
      } 
     }while(length != -1); 

} 

Когда метод выше возвращает вас будет читать весь поток in и написал его к out потока. Ваш метод запуска для вашего потока или runnable может выглядеть примерно так.

public void run() { 

    Socket inSock = null; 
    Socket outSock = null; 
    try{ 
     inSock = new Socket(inHost, inPort); 
     outSock = new Socket(inHost, inPort); 
     /* Set up some socket options here (timeouts, buffers etc)*/ 

     /* Insert pre copy actions */ 

     /* This method won't return until inSock's inputStream hits end of stream. 
     * and all the data has been written to outSock's outputStream and flushed. */ 
     streamCopy(inSock.getInputStream(), outSock.getOutputStream()); 

     /* In order to really do this correctly you should create an 
     * application protocol that verifies the upstream receiver 
     * is actually getting the data before you close the socket. */ 

     /* Insert post copy actions */ 

    }catch(Exception e){ 
     /* Corrective action or logging here */ 
    }finally{ 
     /* Don't forget to close the sockets. */ 
     if(inSock != null){ 
      try{ 
       inSock.close(); 
      }catch(Exception e){ 
       /* Don't care */ 
      } 
     } 
     if(outSock != null){ 
      try{ 
       outSock.close(); 
      }catch(Exception e){ 
       /* Don't care */ 
      } 
     } 
    } 
} 
+0

Если вы назовете флеш, но нечего смывать, это ничего не делает. Нет необходимости устанавливать флаг. –

+0

Вы можете просто написать 'length = clientin.read (data);', который делает то же самое. –

+0

@Peter Я не был уверен, '' length = clientin.read (data); 'попытается прочитать прошлый доступный буфер и заблокировать, чтобы я явно передал длину, чтобы он только читал доступный буфер и возвращал. Хороший звонок на флеш-часть, я пропустил это, поскольку это была копия вставки из кода OPs. – Dev

1

Вы не можете сделать это должным образом в одном потоке. Вам нужно два потока, по одному в каждом направлении. Каждый поток просто читает и записывает, пока не встретит EOS. И не используйте доступные(): просто блокируйте чтение. Установите тайм-аут чтения, чтобы избежать патологических ситуаций.

Смежные вопросы