[英]Reading from Socket
我有問題讓這個簡單的類工作。 它基本上連接到IMAP服務器並讀取橫幅。 但看完所有的字符后,它有些懸而未決。 在調試器中,我可以逐步執行while循環,看到正在讀取所有字符,最終它將從循環中退出。 但是永遠不會到達最后一個System.out.println語句。
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.Socket;
public class TestClient
{
/**
@param args
*/
public static void main( String[] args ) throws Exception
{
Socket socket = new Socket( "imap.1and1.com", 143 );
DataOutputStream os = new DataOutputStream( socket.getOutputStream() );
BufferedReader reader = new BufferedReader( new InputStreamReader( socket.getInputStream() ) );
StringBuilder sb = new StringBuilder();
char ch = (char) reader.read();
while ( ch != -1 ) {
sb.append( ch );
ch = (char) reader.read();
}
System.out.println( sb.toString() ); /// <--- never prints anything and program just hangs..
}
}
如果沒有要讀取的數據,則讀取功能塊,僅在readStream關閉或套接字連接斷開時才會出現。 您應該做的是創建一個協議,在完全讀取數據后斷開連接。 即你應該走出循環
在讀取所有數據后以某種方式斷開連接(為此必須識別已讀取的所有數據)
或者如果您已經閱讀了之前商定的“消息結束”字符串,請自行離開循環。
還有一件事,因為read()阻塞,等待更多數據,建議你應該在后台線程中讀取..
好的,這就是我為解決我的特殊問題所做的。 注意,使用ready()或available()方法並不總是可靠的。 特別是如果服務器需要發送數據,請暫停然后發送更多數據。 在我的情況下,它的工作原理是因為我不希望服務器在響應中間停止並重新啟動。
代碼顯然沒有針對實際使用進行優化。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;
/**
@author Mir Shafiqul Islam <mislam@mirislam.comt>
*/
public class TestClient
{
/**
@param args
*/
public static void main( String[] args ) throws Exception
{
// Open the socket
Socket socket = new Socket( "localhost", 25143 );
// Get a buffered reader
BufferedReader reader = new BufferedReader( new InputStreamReader( socket.getInputStream() ) );
// At this point it is too early to read. So it most likely return false
System.out.println( "Buffer Reader ready? " + reader.ready());
// StringBuilder to hold the response
StringBuilder sb = new StringBuilder();
// Indicator to show if we have started to receive data or not
boolean dataStreamStarted = false;
// How many times we went to sleep waiting for data
int sleepCounter = 0;
// How many times (max) we will sleep before bailing out
int sleepMaxCounter = 50;
// Sleep max counter after data started
int sleepMaxDataCounter = 3;
// How long to sleep for each cycle
int sleepTime = 50;
// Start time
long startTime = System.currentTimeMillis();
// This is a tight loop. Not sure what it will do to CPU
while( true ) {
if ( reader.ready() )
{
sb.append( (char) reader.read() );
// Once started we do not expect server to stop in the middle and restart
dataStreamStarted = true;
} else {
Thread.sleep( sleepTime );
if ( dataStreamStarted && (sleepCounter >= sleepMaxDataCounter) ) {
System.out.println( "Reached max sleep time of " + (sleepMaxDataCounter*sleepTime) + " ms after data started" );
break;
} else {
if (sleepCounter >= sleepMaxCounter) {
System.out.println( "Reached max sleep time of " + (sleepMaxCounter*sleepTime) + " ms. Bailing out" );
// Reached max timeout waiting for data. Bail..
break;
}
}
sleepCounter++;
}
}
long endTime = System.currentTimeMillis();
System.out.println( sb.toString() );
System.out.println( "Time " + (endTime-startTime));
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.