serverSocket interrupting simple Sockets?

mc73

Well-Known Member
Licensed User
Longtime User
I have a server socket (at 192.168.1.10:5001), works ok. At the same time, I created another server socket, at the side of the client (at 192.168.1.20:5011). Why? I want it to receive notifications from the server, without using timers etc.

When I want to notify the client, I create a simple socket (at the server's side, where I have already a server socket running), but then, the server socket at the client's side receives nothing. I get a successful=false at the socket_connected sub.

But, If I close the serversocket at the server's side (no more listening after service gets destroyed), my new socket works ok, and the notification is received by the client (at its server socket).

Is this something to do with the OS? I mean, seems to me like it cannot ping an IP, while in server listening mode. If I notify the server itself, the serversocket at the server acting as a client now, receives the notifications (means probably that it has no problem pinging itself's ip).

Any idea on where I'm going wrong here (I am sure I'm missing something basic perhaps) would be appreciated.
 
Last edited:

mc73

Well-Known Member
Licensed User
Longtime User
Yes, two android devices.
I am searching now, what can it be that disturbs the ping. Perhaps a forgotten open socket? I really don't know.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
If I notify the server itself, the serversocket at the server acting as a client now, receives the notifications (means probably that it has no problem pinging itself's ip).
Communication is always done between two sockets. You should hold a reference to the socket passed to the NewConnection event.
 
Upvote 0

mc73

Well-Known Member
Licensed User
Longtime User
Communication is always done between two sockets. You should hold a reference to the socket passed to the NewConnection event.

I am sorry, I don't quite understand this. At the moment I am creating a small demo which I hope can demonstrate my problem, in which case I'll upload here the source, so that you can tell me where I go wrong (I am sure I'm doing something wrong).
 
Upvote 0

mc73

Well-Known Member
Licensed User
Longtime User
Ok, now I am absolutely stacked. The demo i've just made, isn't pinging either way (ok, sometimes it does ping, rarely). At the same time, my original app works ok (if I load it, of course), with pinging as before, (still remains the initial problem described in this thread).
I have to guess that there is something very simple and at the same time very wrong with my coding (I coded the new ping-version without remembering the exact details of the old one, Perhaps it is a matter of permissions but I can't remember).
Here's the code of the demo. We choose our device (1 or 2), we start our servers, and then try to ping. Attached the demo project.
B4X:
'Activity module
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
Dim IPofThisDevice, IPofTheOtherDevice As String
Dim portOfThisDevice, portOfTheOtherDevice As Int

Dim aNewSocket As Socket 
Dim tmr2 As Timer 
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 ips(2) As String
Dim ports(2) As Int 
ips(0)="192.168.1.5"
ips(1)="192.168.1.20"
ports(0)=5010
ports(1)=5011
Dim btn1, btn2, btn3 As Button 
Dim lbl1, lbl2 As Label 
End Sub

Sub Activity_Create(FirstTime As Boolean)
btn1.Initialize ("btn1")
btn1.Text="Start Service"
Activity.AddView (btn1,0,0,Activity.Width /2,100dip)

btn2.Initialize ("btn2")
btn2.Text="Stop Service"
Activity.AddView (btn2,0,100dip,Activity.Width /2,100dip)

btn3.Initialize ("btn3")
btn3.Text="Ping"
Activity.AddView (btn3,0,200dip,Activity.Width /2,100dip)


Dim res As Int
Dim lst As List
lst.Initialize 
lst.AddAll (Array As Int(1,2))
res=InputList(lst,"Please select device (1 or 2)",0)
If res>-1 Then
    IPofThisDevice=ips(res):portOfThisDevice=ports(res)
    res=1-res
    IPofTheOtherDevice=ips(res):portOfTheOtherDevice=ports(res)
End If

lbl1.Initialize ("")
lbl1.Text="this dev:" & IPofThisDevice & ":" & portOfThisDevice
Activity.Addview(lbl1,0,300dip,Activity.Width ,100dip)

lbl2.Initialize ("")
lbl2.Text="other dev:" & IPofTheOtherDevice & ":" & portOfTheOtherDevice
Activity.Addview(lbl2,0,400dip,Activity.Width ,100dip)

tmr2.Initialize ("tmr2",2000)
tmr2.Enabled =False
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub btn1_click
StopService(ourserver)
StartService(ourserver)
End Sub

Sub btn2_click
StopService(ourserver)
End Sub

Sub btn3_click
pingTheOtherDevice
End Sub

Sub pingTheOtherDevice
' just a ping test
closeStreamsIfOpen
aNewSocket.Initialize ("SocketPing")
aNewSocket.Connect (IPofTheOtherDevice,portOfTheOtherDevice,20)
End Sub

Sub SocketPing_connected(Successful As Boolean )
If Successful=True Then
    Msgbox("ping ok at " & IPofTheOtherDevice & ":" & portOfTheOtherDevice,"ok")
    tmr2.Enabled =True
Else
    Msgbox("ping error at " & IPofTheOtherDevice & ":" & portOfTheOtherDevice,"ok")
    closeStreamsIfOpen
End If

End Sub

Sub closeStreamsIfOpen
' here I put also the aStreams closing process.
If aNewSocket.IsInitialized Then aNewSocket.Close
End Sub

Sub tmr2_tick
Log("tick")
tmr2.Enabled =False
closeStreamsIfOpen
End Sub
And here's the service module

B4X:
'Service module
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
Dim Server As ServerSocket 
Dim socket1 As Socket 
Dim tmr1 As Timer 
End Sub
Sub Service_Create

End Sub

Sub Service_Start (StartingIntent As Intent)
Dim n As Notification
n.Initialize
n.Icon = "icon"
n.AutoCancel =True
n.SetInfo("Just a service module", "Start service","") 
Service.StartForeground (1,n)
Server.Initialize (Main.portOfThisDevice ,"Server")
Server.Listen 
tmr1.Initialize ("tmr1",2000)
tmr1.Enabled =False
End Sub

Sub Service_Destroy
Server.Close 
End Sub

Sub Server_NewConnection (Successful As Boolean, NewSocket As Socket)
    If Successful Then
    Log("successful connection")
        socket1=NewSocket
        tmr1.Enabled =True
    Else
        Log("problem with connection")
    End If
    Server.Listen
End Sub

Sub tmr1_tick
tmr1.Enabled =False
closeSocket
End Sub

Sub closeSocket
socket1.Close 
End Sub
 

Attachments

  • justasocketsdemo.zip
    6.8 KB · Views: 320
Upvote 0

mc73

Well-Known Member
Licensed User
Longtime User
Oh, I know. In the real app, I am using streams and closing everything at the end. Here I just wanted to check if the connected flag turns true or not. In case, a real communication is needed, in order to get it to true, I can recreate the demo soon and get back.
But, Erel, it drives me crazy. Two different apps, one working perfectly, the other not even close. If there isn't a very basic stuff I am missing in the above code, I have no other way than to suppose that somehow the listening serverSocket blocks the outgoing sockets to the second serverSocket located at the client's side. Even if I think this is not true, I just can't believe it.
 
Upvote 0

mc73

Well-Known Member
Licensed User
Longtime User
I assure you that a ServerSocket listening to one port doesn't block other communication.

I'm afraid to say that your code is too complicated for me. Why do you close the sockets? This is not the way to "ping" the other side.
I know, but isn't the successful flag set to true even with the socket open? I mean, should I write data first?
 
Upvote 0

mc73

Well-Known Member
Licensed User
Longtime User
The successful flag is true when a client connected successfully.

If this means that there's no need for writing bytes, then I don't understand why I almost always receive a successfulFalse, while connecting, and at the same time, my normal app is working without a problem, at the very same devices. I mean, it got me too confused.:sign0094: I'll get back, rearranging a but the demo, just to be sure, I'm not missing something here. Thank you!
 
Upvote 0

mc73

Well-Known Member
Licensed User
Longtime User
:sign0161::BangHead::sign0013:

This is what happens when one (that's me) forgets the basics. If you take a closer look at my socket.Connect command at the client's side, you'll find out I'm requesting the connection to be done in 20ms, while of course my intention was to set it to max 20 seconds. Now, everything is working as expected.
I am really sorry, Erel, for your effort to help me, while it was just my coding nonsense.
 
Upvote 0
Top