我最近开始在 J2ME 中编写客户端/服务器应用程序。现在我正在使用 c++ builder 2010 indy 组件(例如 TidTTCPServer)和 J2ME。我的应用程序旨在从远程计算机重新启动 kerio winroute 防火墙服务。 我的服务器应用程序是用 c++ builder 2010 编写的,我将 TidTCTServer 组件放入绑定(bind)到 127.0.0.1:4500 的表单中。那是在本地机器上监听端口 4500。 然后我添加了一个列表框,我需要添加每个即将到来的数据包转换为 UnicodeString。
//void __fastcall TForm1::servExecute(TIdContext *AContext)
UnicodeString s;
UnicodeString txt;
txt=Trim(AContext->Connection->IOHandler->ReadLn());
otvet->Items->Add(txt);
otvet->ItemIndex=otvet->Items->Count-1;
if (txt=="1") {
AContext->Connection->IOHandler->WriteLn("Suhrob");
AContext->Connection->Disconnect();
}
if (txt=="2") {
AContext->Connection->IOHandler->WriteLn("Shodi");
AContext->Connection->Disconnect();
}
//-------------------------------------------- --------------------------------
// void __fastcall TForm1::servConnect(TIdContext *AContext)
++counter;
status->Panels->Items[0]->Text="Connections:" + IntToStr(counter);
status->Panels->Items[1]->Text="Connected to " + AContext->Connection->Socket->Binding->PeerIP + ":" + AContext->Connection->Socket->Binding->PeerPort;
我的客户端代码看起来像这样:
else if (command == send) {
// write pre-action user code here
InputStream is=null;
OutputStream os=null;
SocketConnection client=null;
ServerSocketConnection server=null;
try {
server = (ServerSocketConnection) Connector.open("socket://"+IP.getString()+":"+PORT.getString());
// wait for a connection
client = (SocketConnection) Connector.open("socket://"+IP.getString()+":"+PORT.getString());
// set application-specific options on the socket. Call setSocketOption to set other options
client.setSocketOption(SocketConnection.DELAY, 0);
client.setSocketOption(SocketConnection.KEEPALIVE, 0);
is = client.openInputStream();
os = client.openOutputStream();
// send something to server
os.write("texttosend".getBytes());
// read server response
int c = 0;
while((c = is.read()) != -1) {
// do something with the response
System.out.println((char)c);
}
// close streams and connection
}
catch( ConnectionNotFoundException error )
{
Alert alert = new Alert(
"Error", "Not responding!", null, null);
alert.setTimeout(Alert.FOREVER);
alert.setType(AlertType.ERROR);
switchDisplayable(alert, list);
}
catch (IOException e)
{
Alert alert = new Alert("ERror", e.toString(), null, null);
alert.setTimeout(Alert.FOREVER);
alert.setType(AlertType.ERROR);
switchDisplayable(alert, list);
e.printStackTrace();
}
finally {
if (is != null) {
try {
is.close();
} catch (Exception ex) {
System.out.println("Failed to close is!");
}
try {
os.close();
} catch (Exception ex) {
System.out.println("Failed to close os!");
}
}
if (server != null) {
try {
server.close();
} catch (Exception ex) {
System.out.println("Failed to close server!");
}
}
if (client != null) {
try {
client.close();
} catch (Exception ex) {
System.out.println("Failed to close client!");
}
}
}
我的客户端应用程序与服务器建立连接,但是当我尝试发送数据时,例如
os.write("texttosend".getBytes());
我无法在使用的服务器上获取文本数据。那是我没有在服务器中收到来自客户端的数据包。
txt=Trim(AContext->Connection->IOHandler->ReadLn());
兄弟们,我哪里错了?我这样做可以吗?
或者我是否需要使用 StreamConnection 而不是 SocketConnection?
当我使用 telnet 发送数据时效果很好,字符串将被添加到列表框
telnet 127.0.0.1 4500
texttosend
23
asf
感谢任何帮助!!! 提前致谢!
最佳答案
主要问题是您在服务器端使用了 ReadLn()
。 ReadLn()
不会退出,直到遇到数据终止符(LF
换行符是默认终止符)或发生读取超时(Indy 默认使用无限超时).您的 J2ME 代码未发送任何数据终止符,因此无法告诉 ReadLn()
何时停止读取。它与 Telnet 一起工作的原因是它确实发送换行符。
您的代码的另一个问题是 TIdTCPServer
是一个多线程组件,但您的代码正在以线程不安全的方式更新 UI 组件。您必须与主线程同步,例如使用 Indy 的 TIdSync
和/或 TIdNotify
类,以便从服务器的事件处理程序内部安全地更新您的 UI。
关于c++ - 服务器和客户端之间建立了连接,但无法通过 J2ME 中的 OutputStream 发送数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4593118/