Java Telnet延迟服务器回复
我在telnet通信方面有一个非常奇怪的问题。当我向服务器发送消息时,服务器将在每次发送下一条消息后回复。服务器回复如下所示:Java Telnet延迟服务器回复,java,networking,telnet,Java,Networking,Telnet,我在telnet通信方面有一个非常奇怪的问题。当我向服务器发送消息时,服务器将在每次发送下一条消息后回复。服务器回复如下所示: C: first message S: [// bad IP transmitters adress message 'first message'] C: second message S: [// bad IP transmitters adress message 'second message'] C: third message S: [// ba
C: first message
S: [// bad IP transmitters adress message 'first message']
C: second message
S: [// bad IP transmitters adress message 'second message']
C: third message
S: [// bad IP transmitters adress message 'third message']
//IP地址信息错误
如果我发送“第一条消息”,服务器将不会回复。在我发送“第二条消息”后,服务器将回复第一条消息。每次服务器的回复都会延迟一条消息。
我的沟通是这样的:
C: first message
S: [// bad IP transmitters adress message 'first message']
C: second message
S: [// bad IP transmitters adress message 'second message']
C: third message
S: [// bad IP transmitters adress message 'third message']
如果我使用Google Play Store的Telnet应用程序,它工作得非常完美,通信如下所示:
C: first message
S: [// bad IP transmitters adress message 'first message']
C: second message
S: [// bad IP transmitters adress message 'second message']
C: third message
S: [// bad IP transmitters adress message 'third message']
有什么办法可以修复它吗?非常感谢你
代码:
TCP类
public class TCPclass {
private boolean mRun = false;
String messageFromServer;
private OnMessageReceived mMessageListener = null;
PrintWriter out;
BufferedReader in;
public TCPclass(OnMessageReceived listener) {
mMessageListener = listener;
}
public void stopClient() {
mRun = false;
}
public void sendMessage(String message) {
if (out != null && !out.checkError()) {
message = message + '\r' + '\n';
out.print(message);
out.flush();
Log.i("Terminal", "Message sent.");
}
}
public void start(String hostname, int port) {
mRun = true;
try {
InetAddress serverAddr = InetAddress.getByName(hostname);
Socket socket = new Socket(serverAddr, port);
try {
out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())), true);
// receive the message which the server sends back
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
while (mRun) {
do
{
String messageFromServer = in.readLine();
if (messageFromServer != null && mMessageListener != null) {
mMessageListener.messageReceived(messageFromServer); //append message to Text View
}
messageFromServer = null;
} while (in.ready());
}
} catch (Exception e) {
Log.e("Terminal", "S: Error ", e);
} finally {
socket.close();
}
} catch (Exception e) {
Log.e("Terminal", "Establish connection error " + hostname + " "
+ port);
}
}
public interface OnMessageReceived {
public void messageReceived(String message);
}
}
主要活动类别:
public class MainActivity extends Activity {
private TCPclass mTcpClass;
public String hostname = "127.0.0.1";
public int port = 7011;
TextView serverMessage;
private connectTask mTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final EditText IPaddress = (EditText) findViewById(R.id.eAddress);
final EditText ePort = (EditText) findViewById(R.id.ePort);
final EditText eMessage = (EditText) findViewById(R.id.eMessage);
serverMessage = (TextView) findViewById(R.id.tOutput);
Button okButton = (Button) findViewById(R.id.bOK); //Connect button
okButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) { // connect
// TODO Auto-generated method stub
hostname = IPaddress.getText().toString();
String strPort = ePort.getText().toString();
try {
port = Integer.parseInt(strPort);
} catch (NumberFormatException e) {
Log.e(strPort, "Error port");
}
mTask = new connectTask();
mTask.execute("");
}
});
Button sendButton = (Button) findViewById(R.id.bSend);
sendButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String message = eMessage.getText().toString();
serverMessage.append("C: " + message + "\n");
Log.i("Terminal", "Sending message " + message);
if (mTcpClass != null) {
mTcpClass.sendMessage(message);
}
eMessage.setText("");
}
});
}
public class connectTask extends AsyncTask<String, String, TCPclass> {
@Override
protected TCPclass doInBackground(String... message) {
Log.i("Terminal", "doInBackground.");
mTcpClass = new TCPclass(new TCPclass.OnMessageReceived() {
@Override
// here the messageReceived method is implemented
public void messageReceived(String message) {
// this method calls the onProgressUpdate
publishProgress(message);
}
});
mTcpClass.start(hostname, port);
return null;
}
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
serverMessage.append("S: " + Arrays.toString(values) + "\n");
}
}
公共类MainActivity扩展活动{
私有TCPclass mTcpClass;
公共字符串hostname=“127.0.0.1”;
公共int端口=7011;
TextView服务器消息;
私有连接任务mTask;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
最终EditText IPaddress=(EditText)findViewById(R.id.eadAddress);
最终EditText ePort=(EditText)findViewById(R.id.ePort);
最终EditText eMessage=(EditText)findViewById(R.id.eMessage);
serverMessage=(TextView)findViewById(R.id.tOutput);
按钮OK按钮=(按钮)findViewById(R.id.bOK);//连接按钮
setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图arg0){//connect
//TODO自动生成的方法存根
hostname=IPaddress.getText().toString();
字符串strPort=ePort.getText().toString();
试一试{
端口=整数.parseInt(strPort);
}捕获(数字格式){
Log.e(strPort,“错误端口”);
}
mTask=新连接任务();
mTask.execute(“”);
}
});
按钮sendButton=(按钮)findViewById(R.id.bSend);
setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图v){
String message=eMessage.getText().toString();
serverMessage.append(“C:+message+”\n”);
Log.i(“终端”、“发送消息”+消息);
如果(mTcpClass!=null){
mTcpClass.sendMessage(消息);
}
e消息。setText(“”);
}
});
}
公共类connectTask扩展了AsyncTask{
@凌驾
受保护的TCPclass doInBackground(字符串…消息){
Log.i(“终端”、“后台”);
mTcpClass=新的TCPclass(新的TCPclass.OnMessageReceived(){
@凌驾
//这里实现了messageReceived方法
已接收公共无效消息(字符串消息){
//此方法调用onProgressUpdate
出版进度(信息);
}
});
mTcpClass.start(主机名、端口);
返回null;
}
@凌驾
受保护的void onProgressUpdate(字符串…值){
super.onProgressUpdate(值);
serverMessage.append(“S:+Arrays.toString(values)+“\n”);
}
}
在我看来,服务器可能在某个地方发送了一个空白行或额外的行,而您还没有解释。我是世界上最后一个也是最不喜欢调用available()
或ready()
的人,但可能就是这样:
do
{
String response = in.readLine();
// ...
} while (in.ready());
…至少出于调试的目的,直到您对发送的每一行的响应进行准确排序。请注意,在此处使用
while
循环肯定是不正确的。您没有显示任何接收代码,我猜是在那里缓冲。我将代码添加到我的问题中。请看一看。谢谢。您为什么要使用正在删除此不可信的sendPacket()
来自您的代码?它不符合作者的要求。好吧,我添加了完整的代码。@EJP我在那里添加了“\r”,现在它只在服务器回复每一条延迟的消息时工作。在我问之前,服务器根本没有响应。@我不是在谈论\r,
,尽管这当然应该是\r\n
r RFC,除非您在Telnet中协商过二进制模式。我指的是一种愚蠢的技术,即通过sendMessage()
和sendpackage()
方法一次发送一个字符,并假装TCP不会再次合并它们。sendMessage()
应该只追加\r\n
并直接调用print()
和flush()
。仍然是一样的效果,看起来没有多余的空白行。我从wireshark捕获了服务器消息,它看起来是这样的:在数据中,只有12345和0d=(CR)的错误ip消息奇怪的是,响应以\r(0xd)not \r\n结尾。您能将当前代码编辑到您的问题中吗?我已上载。希望我正确使用了调试代码。它看起来不错,但如果readLine()返回null,您应该关闭连接并退出读取循环。您能用“\r”尝试吗?顺便说一句,如果我删除flush()在代码中,服务器将延迟回复2条消息。也许这一事实也会有所帮助