Socket; send works, but cant get text back

byterbit

Member
Licensed User
Longtime User
Trying to send and receive text to a Java echo server on my cloud linux box. (this will be a key aspect of the app) ; the Java server and client work, test strings go both ways. After a week of work I can now send from an Android client to a Java server and see the server pick up the text in one test program, but unlike the Java client I cant get the Android app to hear the response. No firewalls. I’ve tried all the methods and test code I can find on the site.

If I understand the documentation there is no need, as with Java, to create a looping read structure, but it’s unclear as to how to pick up data from the socket having turned on “listen”; there are many ways to design a program here and without further guidance I could go around in circles for weeks missing success by a small bit of code.

Will (Socket1.InputStream) work by itself or do I need to work with ServerSocket ?

Here's some modified test code I picked up on the site and have worked with. The first example sends successfully to the Java EchoServer. If you can point me to some complete simple working code that listens and displays the echoed text it would help very much.


=================================
Sub Process_Globals
Dim Socket1 As Socket
End Sub

Sub Globals
Dim Button_ARM As Button
Dim Button_STAY As Button
Dim Button_AUTO As Button
Dim Button_OFF As Button
Dim Label_Received As Label
Dim Label_Sent As Label
Dim tr As TextReader
Dim tw As TextWriter
Dim sb As StringBuilder
End Sub

Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("socket32")
Socket1.Initialize("Socket1")

Socket1.Connect("192.168.0.45" , 2222, 2000) 'My IP address goes here


End Sub

Sub Socket1_Connected (Successful As Boolean)
If Successful = False Then
Msgbox(LastException.Message, "Error connecting")
Return
End If
tr.Initialize(Socket1.InputStream)
tw.Initialize(Socket1.OutputStream)

tw.WriteLine("INFO")
Label_Sent.Text = "Sent INFO"
tw.Flush
sb.Initialize
sb.Append(tr.ReadLine)
Label_Received.Text = sb.ToString
'Socket1.Close
End Sub

Sub Button_ARM_Click
tw.WriteLine("O001")
tw.Flush
Label_Sent.Text = "Sent O001"
End Sub

Sub Button_STAY_Click
tw.WriteLine("O002")
tw.Flush
Label_Sent.Text = "Sent O002"
End Sub

Sub Button_OFF_Click
tw.WriteLine("O000")
tw.Flush
Label_Sent.Text = "Sent O000"
End Sub

====================================
Sub Process_Globals
'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.
Dim Socket1 As Socket
Dim ServerSocket1 As ServerSocket
Dim AStreams As AsyncStreams
End Sub
Sub Globals
'These global variables will be redeclared each time the activity is created.
'These variables can only be accessed from this module.

Dim Timer1 As Timer
Dim btnConnect As Button
Dim btnClose As Button
Dim btnTest As Button
Dim lvLog As ListView
Dim lblMyIP As Label
Dim label1 As Label
Dim label2 As Label
Dim label4 As Label
End Sub
Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("socket3")


'Todo: Change typeface of lvLog
' lvlog.Initialize("")
'lvlog.Color ="white"
' lvLog.SingleLineLayout.ItemHeight = 16dip
' lvLog.SingleLineLayout.Label.TextSize = 12
lblMyIP.Initialize("")
label1.text = ServerSocket1.GetMyIP

End Sub


Sub btnTest_Click
Dim Buffer() As Byte
msg = "Hello 2222"
Buffer = msg.GetBytes("UTF8")
Astreams.Write(Buffer)
' lvLog.AddSingleLine ("Sent " & msg)

label2.Text = "Sent " & msg
End Sub
Sub btnConnect_Click
Socket1.Initialize("Socket1")
Socket1.Connect("192.168.0.45",2222,5000)
'lvLog.AddSingleLine ("Do Connect")
End Sub
Sub btnClose_Click
Socket1.Close
' lvLog.AddSingleLine ("Do Close")
label2.Text = "close"
End Sub
Sub Socket1_Connected(Connected As Boolean)As Boolean
If Connected = True Then
AStreams.Initialize(Socket1.InputStream,Socket1.OutputStream,"Astreams")
'lvLog.AddSingleLine ("Is Connected")
label1.text = "connected"
End If
End Sub
Sub Activity_Resume
ServerSocket1.Listen
End Sub

Sub Activity_Pause (UserClosed As Boolean)
If UserClosed Then
Timer1.Enabled = False
Socket1.Close
ServerSocket1.Close 'stop listening
End If
End Sub

Sub ServerSocket1_NewConnection (Successful As Boolean, NewSocket As Socket)
If Successful Then
Socket1 = NewSocket
Timer1.Enabled = True
InputStream1 = Socket1.InputStream
OutputStream1 = Socket1.OutputStream
ToastMessageShow("Connected", True)
Else
Msgbox(LastException.Message, "Error connecting")
End If
ServerSocket1.Listen 'Continue listening to new incoming connections
label4.text = InputStream1
End Su
 

rbsoft

Active Member
Licensed User
Longtime User
Perhaps I'm going blind but I don't see any special start sequence or end delimiters.

No, there isn't anything of that sort in it. I didn't really expect it either for then it would not be a true echo server anymore. An echo server is to receive a message and send (echo) it back to the sender. The only change your echo server makes is converting the message to upper case and to ASCII.

B4X:
// Convert to uppercase
   String upperLine = origLine.toUpperCase() + "\n";
   // Write out as ASCII and flush
   userOutput.write(upperLine.getBytes("ASCII"));
   userOutput.flush();

I do not know if the conversion to ASCII might cause any problems, for JAVA to me is a book with severn seals! But I think some of our Java experts in this forum probably can answer that question.

Maybe you could also try to change that line
B4X:
userOutput.write(upperLine.getBytes("ASCII"));
to
B4X:
userOutput.write(upperLine);
and see what happens.

Rolf
 
Upvote 0

rbsoft

Active Member
Licensed User
Longtime User
I just checked the more simple version of your Java echo server found here:

https://sakai.rutgers.edu/wiki/site/e07619c5-a492-4ebe-8771-179dfe450ae4/echo server tutorial.html

Notice that it says there that the server expects ASCII text.

This tutorial provides a simple introduction to network socket programming in Java. The server will listen for incoming TCP socket connections on a specified port number. When a connection is accepted, it will read a single line of ASCII text from the socket, convert it to uppercase, and write the modified line back to the client.

My little Client example sends UTF8.
B4X:
Buffer = Msg.GetBytes("UTF8")
TcpStreams.Write(Buffer)

You could change this to
B4X:
Buffer = Msg.GetBytes("ASCII")
TcpStreams.Write(Buffer)
Maybe that makes the difference???

Rolf
 
Upvote 0

michelg

Member
Licensed User
Longtime User
EchoClient

rbSoft,

Thank you for posting your code!

I downloaded you code it compiled. However, I noticed that InputStream and OutputStream stayed in red. Is that something wrong?

Can you tell me how to test it using the emulator. Forgive me; I'm very new to Android programming.

Once again thank you,
 
Upvote 0

lagore

Active Member
Licensed User
Longtime User
You are missing a library probably the file one

Sent from my HTC Desire using Tapatalk 2
 
Upvote 0

rbsoft

Active Member
Licensed User
Longtime User
I noticed that InputStream and OutputStream stayed in red. Is that something wrong?
The same here, works ok.

Can you tell me how to test it using the emulator.
I have only tested it on a real device. On the emulator you probably would need to fidget a little with the network settings, but I never was to successful with that.

Rolf
 
Upvote 0

mbatgr

Active Member
Licensed User
Longtime User
Thanks Rolf for ts tiny nice piece of code.
I have implemented a simple VB6 winsocket example. My PC IP is 192.168.1.176 but the B4a code said that Server's IP is 192.168.2.100 and port 9000.
So I have difficulties to make it work. I typed my server IP and port but nothing happened. The very first time running the B4A code, I get an error "connection lost", then immediately I got a message from my firewall that the VB6 need approval, I did allow it, and then pressing the "Connect" button I got consistensly the message "connection lost".

Could you please give me a hand.

Basically I tried to excange text between PC & Device. I can sent text device (server) to PC (client) but not to get back from my PC to the device (having difficulties how to implement the code given (mainly how to get the text in a B4A label) using astreams_NewData (Buffer() As Byte) Sub....
thanks in advance
mike
 
Upvote 0

rbsoft

Active Member
Licensed User
Longtime User
Hi Mike,

here is a slightly modified version. I also included the VB6 server application. (The server is a project I had downloaded somethere years ago, but works fine for testing.)

It works on the emulator as well as on the device. The VB6 Server should be compiled and started as exe.

Rolf
 

Attachments

  • server.jpg
    server.jpg
    12.4 KB · Views: 281
  • androidclient.jpg
    androidclient.jpg
    18.6 KB · Views: 295
  • tcpip.zip
    42 KB · Views: 361
Upvote 0

mbatgr

Active Member
Licensed User
Longtime User
thanks a lot. now i have to solve the problems of non-latin Greek characters. Have you got any idea. I'm looking on it all evening but nothing really helpful.

Also, I removed the line
AStreams.Write(Array As Byte(254)) of SendData(msg As String) Sub without any problem
Is it neccessary to end with ascii 254?

Lastly, the only part of the code I don't understand is the

signedb = Buffer(i)
unsignedi = Bit.AND(0xff, signedb)

of AStreams_NewData (Buffer() As Byte) Sub


thank you again, Rolf

PS I'd like to mention that reading a MS Access Database with B4A, I could see the greek characters properly to my device
 
Upvote 0

rbsoft

Active Member
Licensed User
Longtime User
Also, I removed the line
AStreams.Write(Array As Byte(254)) of SendData(msg As String) Sub without any problem
Is it neccessary to end with ascii 254?
No there is no need for it. I just needed it for one of my application servers where I implemented my own protocol structure. ascii 254 served as end delimiter there.

Rolf
 
Upvote 0

mbatgr

Active Member
Licensed User
Longtime User
So , I suppose that you don't have any suggestion for texting non-latin characters. If I knew that there is no straight solution in B4A it, I should work with translating tables...
mike
 
Upvote 0

rbsoft

Active Member
Licensed User
Longtime User
That might work with using a different charset, but I did not have time yet to check that out. I have never done it so far.

Rolf
 
Upvote 0

mbatgr

Active Member
Licensed User
Longtime User
I tried with Windows-1252 and ISO but it doesn't work. I'm just thinking if there is another way using text.reader etc
anyway, thank you for your help and th time you dedicated for it. cheers
mike
 
Upvote 0

rbsoft

Active Member
Licensed User
Longtime User
Lastly, the only part of the code I don't understand is the
signedb = Buffer(i)
unsignedi = Bit.AND(0xff, signedb)
of AStreams_NewData (Buffer() As Byte) Sub

This part you can leave out if you are just sending normal text within the limits of Asccii < 128. In the German language we have the so called Umlaute which are in the area of Ascii 128 to 255. That code makes it readable on Android.

Rolf
 
Upvote 0

mbatgr

Active Member
Licensed User
Longtime User
I think that may this is my case as the greek character are in this area. If you explain to me the
unsignedi = Bit.AND(0xff, signedb) may i can work with it.
At the moment I'm working on converting the greek letters to english before sending them that is π -> p. Similar code in VB6, too

ps. i now see why you used the 254 char :)
 
Last edited:
Upvote 0

rbsoft

Active Member
Licensed User
Longtime User
Upvote 0
Top