J2ME中服务器和客户端之间建立了连接,但无法通过OutputStream发送数据
我最近开始在 J2ME 中编写客户端/服务器应用程序。现在我正在使用 c++ builder 2010 indy 组件(例如 TidTTCPServer)和 J2ME。我的应用程序旨在从远程计算机重新启动 kerio winroute 防火墙服务。 我的服务器应用程序是用 c++ builder 2010 编写的,我将 TidTCTServer 组件放入绑定到 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
任何帮助表示赞赏! 提前致谢!
I started to program client/server applications in J2ME recently.Now I'm working with c++ builder 2010 indy components (e.g. TidTTCPServer) and J2ME. My application is designed to restart the kerio winroute firewall service from a remote machine.
My server application is written in c++ builder 2010, I've put a TidTCTServer component into a form which binded to 127.0.0.1:4500. That's listening on port 4500 in local machine.
Then i've added a listbox that i need to add every upcoming packets converted to 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;
and my client side code looks smth like this:
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!");
}
}
}
my client application gets connected with the server but when i try to send data such as
os.write("texttosend".getBytes());
I cannot get text data on the server using. That's I am not getting sent packets in the server from client.
txt=Trim(AContext->Connection->IOHandler->ReadLn());
Guys, where am I wrong? is the way i'm doing is ok?
Or do I need to use StreamConnection instead of SocketConnection?
And when i use telnet to send data it works cool, strings will be added to listbox
telnet 127.0.0.1 4500
texttosend
23
asf
Any help is appreciated !!!
Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
主要问题是您在服务器端使用
ReadLn()
。ReadLn()
不会退出,直到遇到数据终止符(LF
换行符是默认终止符)或发生读取超时(Indy 默认使用无限超时) )。您的 J2ME 代码没有发送任何数据终止符,因此无法告诉ReadLn()
何时停止读取。它与 Telnet 一起使用的原因是它确实发送换行符。您的代码的另一个问题是
TIdTCPServer
是一个多线程组件,但您的代码正在以线程不安全的方式更新 UI 组件。您必须与主线程同步,例如使用 Indy 的TIdSync
和/或TIdNotify
类,以便从服务器的事件处理程序内部安全地更新您的 UI。The main problem is that you are using
ReadLn()
on the server end.ReadLn()
does not exit until a data terminator is encountered (aLF
line break character is the default terminator) or if a reading timeout occurs (Indy uses infinite timeouts by default). Your J2ME code is not sending any data terminator, so there is nothing to tellReadLn()
when to stop reading. The reason it works with Telnet is because it does send line break characters.The other problem with your code is that
TIdTCPServer
is a multi-threaded component, but your code is updating the UI components in a thread-unsafe manner. You MUST synchronize with the main thread, such as by using Indy'sTIdSync
and/orTIdNotify
classes, in order to update your UI safely from inside of the server's event handlers.是的,发送字节后需要调用flush方法,但是......最后......
然后我尝试将我的连接代码包含在一个实现 Runnable 的新线程中,该线程完美运行。现在我发现我错在哪里了!!!!!!!!!!!!
您需要将上面的代码包含在以下块中。
Yes, flush method is necessary to call after sending bytes, but ..... finally....
then i tried to include my connection code in a new thread that implements Runnable worked perfectly. Now I've found where I was wrong!!!!!!!!!!!!!!
That's guys you need to include above code in the following block.
尝试
如果没有,请尝试写入已知的工作服务器,而不是您自己创建的服务器(类似于 将“HELO”写入 SMTP 服务器),这将帮助您找出错误发生在哪一端。
Try OutputStream.flush()?
If not, try writing to a known working server, instead of one you've created yourself (something like writing "HELO" to an SMTP server), this will help you figure out which end the error is at.