[英]Issue with Socket Streams in Java “Telnet” Code?
我在從“ Telnet”接口的C / C ++過渡到Java時遇到一些麻煩。 我希望能夠與網卡建立連接,該網卡在啟動命令行界面后等待連接並向客戶端提供提示(“確定>”)。 這對於我編寫的C和C#客戶端都可以正常工作,但是Java給了我一些問題。 我已經附上了我從一些在線示例中獲取的代碼,但是到目前為止,我只能確定正在創建套接字。
碼:
private boolean CreateTelnetSession()
{
try
{
_socket = new Socket();
_socket.connect(new InetSocketAddress(_ipAddr, _ipPort));
_socket.setSoTimeout(10000);
_socket.setKeepAlive(true);
_out = new PrintWriter(_socket.getOutputStream(), true);
_in = new BufferedReader(new InputStreamReader(_socket.getInputStream()));
_out.println("\r\n");
System.out.println(_in.readLine());
return true;
}
catch(Exception e)
{
System.out.println("Exception!");
}
return false;
}
套接字SEEMS可以正確創建,並且在程序關閉時,我可以看到會話正在我想要交談的卡上關閉,但是我沒有看到回車符/換行符符合我的期望,或者通過InputStream返回提示。 這可能是字符編碼問題嗎? 我在流中做錯了什么(穿過它們!!!)? 有什么見解嗎? 當我克服了這個最初的學習曲線時,我想承認Java使這些套接字讀寫變得如此容易,但是直到那時...
我讀了這篇文章: 使用套接字的Java簡單telnet客戶端
似乎與我所面臨的挑戰相似,但事實並非如此。 如果有人在這里看到可以解決我問題的內容,我願意代表銷售,因此請直截了當地告訴我我錯過了什么。
編輯:
private boolean CreateTelnetSession()
{
try
{
_socket = new Socket();
_socket.connect(new InetSocketAddress(_ipAddr, _ipPort));
_socket.setSoTimeout(10000);
_socket.setKeepAlive(true);
_out = new DataOutputStream(_socket.getOutputStream());
_in = new DataInputStream(_socket.getInputStream());
_outBuffer = ByteBuffer.allocate(2048);
_outBuffer.order(ByteOrder.LITTLE_ENDIAN);
_inBuffer = ByteBuffer.allocate(2048);
_inBuffer.order(ByteOrder.LITTLE_ENDIAN);
System.out.println("Connection Response: " + _in.read(_inBuffer.array()));
System.out.println("Response: " + WriteCommand("DRS\r\n"));
return true;
}
catch(Exception e)
{
System.out.println("Exception!");
}
return false;
}
private String WriteCommand(String command)
{
try
{
_outBuffer = encoder.encode(CharBuffer.wrap(command));
_out.write(_outBuffer.array());
_out.flush();
_in.read(_inBuffer.array());
String retString = decoder.decode(_inBuffer).toString();
return retString.substring(0, retString.indexOf('>') + 1);
}
catch(Exception e)
{
System.out.println("Exception!");
}
return "E1>";
}
有很多事情需要清理,我將嘗試是否需要以這種方式進行清理,但這是“解決方案”的要旨。 最大的殺手是字節序。 應當再次提及,這是丑陋且非生產性的代碼,但是任何其他輸入仍將受到贊賞。
我有幾件可以嘗試的東西。 您正在使用PrintWriter作為輸出,這是一個相當高級的Writer(即,它封裝了您的很多東西)。 我擔心的是,PrintWriter中的println()方法在結尾處自動添加了一個行終止字符(適用於您的操作系統)。 因此,您真正發送的是“ / r / n(行終止符)”,因此在Unix框上您將發送“ / r / n / n”。
我建議切換到DataOutputStream,它使您對發送的原始字節有更多控制: http : //docs.oracle.com/javase/6/docs/api/java/io/DataOutputStream.html
請記住,如果切換到DataOutputStream,則需要在輸出流上調用flush。
我的另一個想法是這可能是一種流行病。 Java嚴格是Big Endian(網絡字節順序)。 您的“卡片”是否有可能以小端順序讀取內容? 如果您需要通過網絡以低位優先順序寫(如果您的卡是壞網民!),則需要使用ByteBuffer,將其順序設置為低位順序。 向其寫入字節,然后將字節緩沖區中的字節寫入DataOutputStream。
我可能也會為您的輸入流切換到DataInputStream。 readline()僅在看到換行符后才返回。 您的卡是否在響應中返回換行符?
我的最后一個想法是您的println方法可能有一個錯誤,並且您不知道該錯誤,因為PrintWriter不會引發異常。 PrintWriter JavaDocs說:
“此類中的方法永遠不會拋出I / O異常,盡管它的某些構造函數可能會發生。客戶端可以通過調用checkError()來查詢是否發生了任何錯誤。”
希望我漫不經心的回應中的某些內容對您有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.