02-20-2013 07:16 PM
Hello ,
I have created a socket connection between a pc(sever, win32) and a blackberry(client) and I have two issue regarding that :
-when I send a string to the sever I get unexpected result, I doubt if it is an encoding problem between the platforms.
-when I try to receive data, (an array of char as a string object), to the client the application freeze(drawing and event handling , so basically the main ui thread ), even if I did all connection stuff in a separated thread, until I close the sever and also no data is received.
I let the codes below and would value any reply from you.
C++, win32 console application:
SOCKET _socket;
int _tmain(int argc, _TCHAR* argv[])
{
if(start_sever(_socket) ){
char r_msg[26];
recv(_socket, r_msg, 26, 0);
std::cout<< "receive : " << r_msg << std::endl;
char *s_msg="Welcome client";
send(_socket,szMessage,strlen(s_msg),0);
std::cout<< "send : " << s_msg <<std::endl;
Sleep(500);
shutdown(_socket, SD_SEND);
//closesocket(_socket);
//WSACleanup();
}else{
std::cout<< "Cannot initialize sever"<< std::endl ;
}
system("PAUSE");
return 0;
}
BOOL start_sever( SOCKET Socket){
WSADATA WsaDat;
if(WSAStartup(MAKEWORD(2,2),&WsaDat)!=0)
{
std::cout<<"WSA Initialization failed!\r\n";
WSACleanup();
system("PAUSE");
return false;
}
Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(Socket==INVALID_SOCKET)
{
std::cout<<"Socket creation failed.\r\n";
WSACleanup();
system("PAUSE");
return false;
}
SOCKADDR_IN serverInf;
serverInf.sin_family=AF_INET;
serverInf.sin_addr.s_addr= INADDR_ANY;
serverInf.sin_port=htons(8888);
if(bind(Socket,(SOCKADDR*)(&serverInf),sizeof(serv
{
std::cout<<"Unable to bind socket!\r\n";
WSACleanup();
system("PAUSE");
return false;
}
listen(Socket,1);
SOCKET TempSock=SOCKET_ERROR;
std::cout<< "build 1.0.2\n";
while(TempSock==SOCKET_ERROR)
{
std::cout<<"Waiting for incoming connections...\r\n";
TempSock=accept(Socket,NULL,NULL);
}
Socket=TempSock;
std::cout<<"Client connected!\r\n\r\n";
return true;
}
Java blackberry platform :
public class Socket extends MainScreen {
//-my current ipv4 address is set by default to avoid to reset it at each test
TextField ip_text_field= new TextField("IP address : ", "192.168.65.1");
//- the sever is waiting for any connection at this port("8888")
TextField port_text_field= new TextField("Port : ", "8888");
ButtonField go_button_field= new ButtonField("Connect", Field.FIELD_HCENTER){
protected boolean invokeAction(int action){
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
try {
open_connection();
}catch (Exception e){
e.printStackTrace();
Dialog.alert(e.getMessage() );
}
}
});
return true;
}
};
public Socket(){
super();
setTitle("[socket sample]");
add(ip_text_field);ip_text_field.setMargin(20, 0, 0, 0);
add(port_text_field);port_text_field.setMargin(30, 0, 0, 0);
add(go_button_field);go_button_field.setMargin(30, 0, 0, 0);
}
public boolean onClose(){
this.close();
return true;
}
StreamConnection _con;
DataInputStream _in;
OutputStreamWriter _out;
public void open_connection() throws Exception{
_con=(StreamConnection)Connector.open("socket://"+ ip_text_field.getText() + ":" + port_text_field.getText() +
";deviceside=true;interface=wifi");
this.add(new TextField("", "connected to the sever successfully") );
_in= _con.openDataInputStream();
_out= new OutputStreamWriter(_con.openDataOutputStream() );
String msg="welcome to the client \r\n";
_out.write(msg);
String r_msg= _in.readUTF();
this.add(new TextField("read from sever : ", r_msg) );
_out.flush();
_in.close();
_out.close();
_con.close();
this.add(new TextField("", "data has been exchange") );
}
}
Thank for your help.
Solved! Go to Solution.
02-20-2013 07:33 PM
You are processing on the Event Thread.
You have the following code:
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
try {
open_connection();
....
Now invokeLater basically tells the OS that the associated Runnable should be executed on the Event Thread. YOu need to start a separate Thread. So extend Thread, add your code in the run() method and then start the Thread using start().(not run()). Then you will be executing the networking processing on a separate Thread.
This will cause you problems updating the Ui. Have a look at this to help:
The impression that invokelater means a separate Thread is a common misconception. I recommend that you review this:
http://supportforums.blackberry.com/t5/Java-Develo
In addition, I recommend that you have a look at the socketDemo that should be included as a sample - if not you will find it on github:
02-21-2013 12:11 AM
02-21-2013 04:08 AM
Being honest here, I don't think you need any more tips.
You say "..still the same when I try to red from the sever." I'm not 100% sure what you mean by this, but if you mean it still causes the UI to glitch, then that is because you have not moved the processing off the Event Thread.
In your situation, I would start by getting the sample working. Then rework the sample code to suit your situation The Java server code is very easy to test, most people have Java on their PC and if you don't, you can download and install it very quickly.
Let us know if you can't get the sample working.
02-21-2013 04:30 AM
You might be interested to review the following Thread too:
02-21-2013 08:00 AM
02-21-2013 10:24 AM
Good to hear.
I think you will find encoding is actually easier that you might think.
If you are only sending text data, then I would suggest that you just convert everything to UTF8 and send only UTF8 bytes.
If you are sending binary data, then do nothing.
If you are sending a mixture of text and Binary, then you will have to look at what your server provides.
I would recommend that you use something like JSON as the underlying byte protocol. Personally I find JSON easier than XML.
Good luck.