Socket Problem

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Socket Problem

Emiliano Pérez-2
Hello, this is my first post in this list, I´m Emiliano Pérez.

I´m working on an service that is meant to discover other machines in
the LAN running the same service. This is done by an object running 2
threads, the first has a receiving socket on regular udp. and the other
has a receiving multicast (managed as a strategy) socket. The broadcast
socket is for detecting the other machines, and the udp socket is for
pear to pear communication. The sockets receive commands and send
acknowledgments. When i start the object it sends an "enter command" to
the multicast ip, so the others can "see" it and send him an
acknowledgment through the p2p socket. The problem comes up when the
local object receives an "Enter" command from himself and sends an
Acknowledge command to the sender (self) . When it sends that last
command it keeps getting a BADARGS_ERROR exception from the p2p socket.
To explain a little more what it is that i do i copy some methods below
that i hope, will help you to understand.
The code:

" - the start method "

->start
    self isActive ifFalse:[
                            self prepareSocketAt: self listeningPort.  
             " newUDPserverAtPort:xxxx "
                            self broadcastingStrategy open.            
              " in this case a multicast socket "
                            self turnOn.                              
              " this method sets isActive in true "
                            self launchPeerThread.
                            self launchBroadcastingThread.
                            self advertise.].                            
            " sendBroadcastCommand: EnterCommand "

->launchPeerThread
        [
        [self isActive] whileTrue:[ | cmd |
                                cmd:=self receivePeerCommand.
                                cmd executeOn: self.
                                ].
        self broadcastingStrategy close.] fork.

" - the broadcast thread is the same, only receiveBroadcastCommand
instead of receiveBroadcastCommand ".


->receivePeerCommand

        | peerAddress buffer size |      

        buffer:=ByteArray new: self defaultBufferSize.
        peerAddress:=IPSocketAddress new.
        self listeningSocket readWait.
        size:=self listeningSocket receiveFrom: peerAddress buffer:
buffer start: 1 for: buffer size.
        ^DiscovererCommand decodeFrom: (buffer copyFrom: 1 to: size).

MulticastStrategy->receiveBroadcast

    | buffer size |

    buffer := ByteArray new: self defaultBufferSize.
    self broadcastingSocket readWait.
    size := self broadcastingSocket receiveFrom: self inBroadcastingAddress
                buffer: buffer.
    ^buffer copyFrom: 1 to: size

" this is the code that starts the multicast socket "

MulticastStrategy->open

    self broadcastingSocket: (SocketAccessor family: SocketAccessor AF_INET
                type: SocketAccessor SOCK_DGRAM).
    self broadcastingSocket soReuseaddr: true.
    self broadcastingSocket bindTo: self inBroadcastingAddress.
    self broadcastingSocket
        join: (self multicastRequestFrom: self broadcastingGroup)


" this is the code that is executed when the command is received "

EnterCommand->doExecuteOn: aReceiver
        aReceiver addHost: self senderAddress.
        aReceiver sendAcknowledgeTo: self senderAddress.


Thats the important code until i´m able to isolate the problem a bit
more. The error is not constant, but it appears about 60% of the times
when i start the object.

Thanks in advance,
Emiliano.

Reply | Threaded
Open this post in threaded view
|

Re: Socket Problem

Emiliano Pérez-3
Hi, it´s me again, i´m still getting the problem. I´ve tried different
solutions, and it still doesn´t works.

a little more info:

This is the p2p sending code:

    sendPeerCommand: aCommand to: aPeerAddress
        self listeningSocket writeWait.
        self listeningSocket sendTo: aPeerAddress buffer: (aCommand
encodeCommand).

- if i put the writeWait before sending it gives me the
ERROR_BAD_COMMAND from the primitive 685 coming from the writeWait.
- if i don´t put it, it gives me the BADARGS_ERROR in the primitive 676
coming from the sendTo:buffer: message.

I emphasize the fact that the error appears only when sending an
Acknowledgment, in other words it´s the executeOn: from a received
command who calls the sendPeerCommand message.

Any help on the "why" or the "how" of this 2 errors wold be very
appreciated too.
Thanks,
Emiliano.

Emiliano Pérez escribió:

> Hello, this is my first post in this list, I´m Emiliano Pérez.
>
> I´m working on an service that is meant to discover other machines in
> the LAN running the same service. This is done by an object running 2
> threads, the first has a receiving socket on regular udp. and the
> other has a receiving multicast (managed as a strategy) socket. The
> broadcast socket is for detecting the other machines, and the udp
> socket is for pear to pear communication. The sockets receive commands
> and send acknowledgments. When i start the object it sends an "enter
> command" to the multicast ip, so the others can "see" it and send him
> an acknowledgment through the p2p socket. The problem comes up when
> the local object receives an "Enter" command from himself and sends an
> Acknowledge command to the sender (self) . When it sends that last
> command it keeps getting a BADARGS_ERROR exception from the p2p
> socket. To explain a little more what it is that i do i copy some
> methods below that i hope, will help you to understand.
> The code:
>
> " - the start method "
>
> ->start
>    self isActive ifFalse:[
>                            self prepareSocketAt: self listeningPort.  
>             " newUDPserverAtPort:xxxx "
>                            self broadcastingStrategy open.            
>              " in this case a multicast socket "
>                            self turnOn.                              
>              " this method sets isActive in true "
>                            self launchPeerThread.
>                            self launchBroadcastingThread.
>                            self
> advertise.].                                       "
> sendBroadcastCommand: EnterCommand "
>
> ->launchPeerThread
>        [
>        [self isActive] whileTrue:[ | cmd |
>                                cmd:=self receivePeerCommand.
>                                cmd executeOn: self.
>                                ].
>        self broadcastingStrategy close.] fork.
>
> " - the broadcast thread is the same, only receiveBroadcastCommand
> instead of receiveBroadcastCommand ".
>
>
> ->receivePeerCommand
>
>        | peerAddress buffer size |      
>        buffer:=ByteArray new: self defaultBufferSize.
>        peerAddress:=IPSocketAddress new.
>        self listeningSocket readWait.
>        size:=self listeningSocket receiveFrom: peerAddress buffer:
> buffer start: 1 for: buffer size.
>        ^DiscovererCommand decodeFrom: (buffer copyFrom: 1 to: size).
>
> MulticastStrategy->receiveBroadcast
>
>    | buffer size |
>
>    buffer := ByteArray new: self defaultBufferSize.
>    self broadcastingSocket readWait.
>    size := self broadcastingSocket receiveFrom: self
> inBroadcastingAddress
>                buffer: buffer.
>    ^buffer copyFrom: 1 to: size
>
> " this is the code that starts the multicast socket "
>
> MulticastStrategy->open
>
>    self broadcastingSocket: (SocketAccessor family: SocketAccessor
> AF_INET
>                type: SocketAccessor SOCK_DGRAM).
>    self broadcastingSocket soReuseaddr: true.
>    self broadcastingSocket bindTo: self inBroadcastingAddress.
>    self broadcastingSocket
>        join: (self multicastRequestFrom: self broadcastingGroup)
>
>
> " this is the code that is executed when the command is received "
>
> EnterCommand->doExecuteOn: aReceiver
>        aReceiver addHost: self senderAddress.
>        aReceiver sendAcknowledgeTo: self senderAddress.
>
>
> Thats the important code until i´m able to isolate the problem a bit
> more. The error is not constant, but it appears about 60% of the times
> when i start the object.
>
> Thanks in advance,
> Emiliano.
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Socket Problem

kobetic
I don't see anything obviously wrong with your code on a quick look, but I might need a refresh on broad/mutli-casting, it's been a while :-). However I'd like to point out that Opentalk supports both (see parcel Opentalk-Groups and the relevant chapters in OpentalkDevGuide.pdf). If nothing else, you can try if it works on your network and possibly compare what's different. These things are notoriously sensitive to all kinds of things.

HTH,

Martin

Emiliano Pérez wrote:

> Hi, it´s me again, i´m still getting the problem. I´ve tried different
> solutions, and it still doesn´t works.
>
> a little more info:
>
> This is the p2p sending code:
>
>    sendPeerCommand: aCommand to: aPeerAddress
>        self listeningSocket writeWait.
>        self listeningSocket sendTo: aPeerAddress buffer: (aCommand
> encodeCommand).
>
> - if i put the writeWait before sending it gives me the
> ERROR_BAD_COMMAND from the primitive 685 coming from the writeWait.
> - if i don´t put it, it gives me the BADARGS_ERROR in the primitive 676
> coming from the sendTo:buffer: message.
>
> I emphasize the fact that the error appears only when sending an
> Acknowledgment, in other words it´s the executeOn: from a received
> command who calls the sendPeerCommand message.
>
> Any help on the "why" or the "how" of this 2 errors wold be very
> appreciated too.
> Thanks,
> Emiliano.
>
> Emiliano Pérez escribió:
>> Hello, this is my first post in this list, I´m Emiliano Pérez.
>>
>> I´m working on an service that is meant to discover other machines in
>> the LAN running the same service. This is done by an object running 2
>> threads, the first has a receiving socket on regular udp. and the
>> other has a receiving multicast (managed as a strategy) socket. The
>> broadcast socket is for detecting the other machines, and the udp
>> socket is for pear to pear communication. The sockets receive commands
>> and send acknowledgments. When i start the object it sends an "enter
>> command" to the multicast ip, so the others can "see" it and send him
>> an acknowledgment through the p2p socket. The problem comes up when
>> the local object receives an "Enter" command from himself and sends an
>> Acknowledge command to the sender (self) . When it sends that last
>> command it keeps getting a BADARGS_ERROR exception from the p2p
>> socket. To explain a little more what it is that i do i copy some
>> methods below that i hope, will help you to understand.
>> The code:
>>
>> " - the start method "
>>
>> ->start
>>    self isActive ifFalse:[
>>                            self prepareSocketAt: self listeningPort.  
>>             " newUDPserverAtPort:xxxx "
>>                            self broadcastingStrategy open.            
>>              " in this case a multicast socket "
>>                            self turnOn.                              
>>              " this method sets isActive in true "
>>                            self launchPeerThread.
>>                            self launchBroadcastingThread.
>>                            self
>> advertise.].                                       "
>> sendBroadcastCommand: EnterCommand "
>>
>> ->launchPeerThread
>>        [
>>        [self isActive] whileTrue:[ | cmd |
>>                                cmd:=self receivePeerCommand.
>>                                cmd executeOn: self.
>>                                ].
>>        self broadcastingStrategy close.] fork.
>>
>> " - the broadcast thread is the same, only receiveBroadcastCommand
>> instead of receiveBroadcastCommand ".
>>
>>
>> ->receivePeerCommand
>>
>>        | peerAddress buffer size |             buffer:=ByteArray new:
>> self defaultBufferSize.
>>        peerAddress:=IPSocketAddress new.
>>        self listeningSocket readWait.
>>        size:=self listeningSocket receiveFrom: peerAddress buffer:
>> buffer start: 1 for: buffer size.
>>        ^DiscovererCommand decodeFrom: (buffer copyFrom: 1 to: size).
>>
>> MulticastStrategy->receiveBroadcast
>>
>>    | buffer size |
>>
>>    buffer := ByteArray new: self defaultBufferSize.
>>    self broadcastingSocket readWait.
>>    size := self broadcastingSocket receiveFrom: self
>> inBroadcastingAddress
>>                buffer: buffer.
>>    ^buffer copyFrom: 1 to: size
>>
>> " this is the code that starts the multicast socket "
>>
>> MulticastStrategy->open
>>
>>    self broadcastingSocket: (SocketAccessor family: SocketAccessor
>> AF_INET
>>                type: SocketAccessor SOCK_DGRAM).
>>    self broadcastingSocket soReuseaddr: true.
>>    self broadcastingSocket bindTo: self inBroadcastingAddress.
>>    self broadcastingSocket
>>        join: (self multicastRequestFrom: self broadcastingGroup)
>>
>>
>> " this is the code that is executed when the command is received "
>>
>> EnterCommand->doExecuteOn: aReceiver
>>        aReceiver addHost: self senderAddress.
>>        aReceiver sendAcknowledgeTo: self senderAddress.
>>
>>
>> Thats the important code until i´m able to isolate the problem a bit
>> more. The error is not constant, but it appears about 60% of the times
>> when i start the object.
>>
>> Thanks in advance,
>> Emiliano.
>>
>>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Socket Problem

kobetic
In reply to this post by Emiliano Pérez-3
Actually, maybe few notes. You're using terms like listeningSocket, broadcastingSocket and using multicast join: as well, so I'm wondering if there's some confusion here. Listening here seems to refer to normal UDP socket. The broadcasting socket seems to be a multicasting socket actually, however it all depends on the actual IP addresses you're using. Broadcasting address is usually the last address in your network address space (e.g. 192.168.1.255/24) and there's no joining or leaving. Everybody can listen in on those messages. Multicasting addresses are from the dedicated range 224... - 23?... (I don't remember the upper limit) and you need to explicitly join: and leave: a specific address. Anyway, I wonder if you've got all that lined up properly.

HTH,

Martin

Emiliano Pérez wrote:

> Hi, it´s me again, i´m still getting the problem. I´ve tried different
> solutions, and it still doesn´t works.
>
> a little more info:
>
> This is the p2p sending code:
>
>    sendPeerCommand: aCommand to: aPeerAddress
>        self listeningSocket writeWait.
>        self listeningSocket sendTo: aPeerAddress buffer: (aCommand
> encodeCommand).
>
> - if i put the writeWait before sending it gives me the
> ERROR_BAD_COMMAND from the primitive 685 coming from the writeWait.
> - if i don´t put it, it gives me the BADARGS_ERROR in the primitive 676
> coming from the sendTo:buffer: message.
>
> I emphasize the fact that the error appears only when sending an
> Acknowledgment, in other words it´s the executeOn: from a received
> command who calls the sendPeerCommand message.
>
> Any help on the "why" or the "how" of this 2 errors wold be very
> appreciated too.
> Thanks,
> Emiliano.
>
> Emiliano Pérez escribió:
>> Hello, this is my first post in this list, I´m Emiliano Pérez.
>>
>> I´m working on an service that is meant to discover other machines in
>> the LAN running the same service. This is done by an object running 2
>> threads, the first has a receiving socket on regular udp. and the
>> other has a receiving multicast (managed as a strategy) socket. The
>> broadcast socket is for detecting the other machines, and the udp
>> socket is for pear to pear communication. The sockets receive commands
>> and send acknowledgments. When i start the object it sends an "enter
>> command" to the multicast ip, so the others can "see" it and send him
>> an acknowledgment through the p2p socket. The problem comes up when
>> the local object receives an "Enter" command from himself and sends an
>> Acknowledge command to the sender (self) . When it sends that last
>> command it keeps getting a BADARGS_ERROR exception from the p2p
>> socket. To explain a little more what it is that i do i copy some
>> methods below that i hope, will help you to understand.
>> The code:
>>
>> " - the start method "
>>
>> ->start
>>    self isActive ifFalse:[
>>                            self prepareSocketAt: self listeningPort.  
>>             " newUDPserverAtPort:xxxx "
>>                            self broadcastingStrategy open.            
>>              " in this case a multicast socket "
>>                            self turnOn.                              
>>              " this method sets isActive in true "
>>                            self launchPeerThread.
>>                            self launchBroadcastingThread.
>>                            self
>> advertise.].                                       "
>> sendBroadcastCommand: EnterCommand "
>>
>> ->launchPeerThread
>>        [
>>        [self isActive] whileTrue:[ | cmd |
>>                                cmd:=self receivePeerCommand.
>>                                cmd executeOn: self.
>>                                ].
>>        self broadcastingStrategy close.] fork.
>>
>> " - the broadcast thread is the same, only receiveBroadcastCommand
>> instead of receiveBroadcastCommand ".
>>
>>
>> ->receivePeerCommand
>>
>>        | peerAddress buffer size |             buffer:=ByteArray new:
>> self defaultBufferSize.
>>        peerAddress:=IPSocketAddress new.
>>        self listeningSocket readWait.
>>        size:=self listeningSocket receiveFrom: peerAddress buffer:
>> buffer start: 1 for: buffer size.
>>        ^DiscovererCommand decodeFrom: (buffer copyFrom: 1 to: size).
>>
>> MulticastStrategy->receiveBroadcast
>>
>>    | buffer size |
>>
>>    buffer := ByteArray new: self defaultBufferSize.
>>    self broadcastingSocket readWait.
>>    size := self broadcastingSocket receiveFrom: self
>> inBroadcastingAddress
>>                buffer: buffer.
>>    ^buffer copyFrom: 1 to: size
>>
>> " this is the code that starts the multicast socket "
>>
>> MulticastStrategy->open
>>
>>    self broadcastingSocket: (SocketAccessor family: SocketAccessor
>> AF_INET
>>                type: SocketAccessor SOCK_DGRAM).
>>    self broadcastingSocket soReuseaddr: true.
>>    self broadcastingSocket bindTo: self inBroadcastingAddress.
>>    self broadcastingSocket
>>        join: (self multicastRequestFrom: self broadcastingGroup)
>>
>>
>> " this is the code that is executed when the command is received "
>>
>> EnterCommand->doExecuteOn: aReceiver
>>        aReceiver addHost: self senderAddress.
>>        aReceiver sendAcknowledgeTo: self senderAddress.
>>
>>
>> Thats the important code until i´m able to isolate the problem a bit
>> more. The error is not constant, but it appears about 60% of the times
>> when i start the object.
>>
>> Thanks in advance,
>> Emiliano.
>>
>>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Socket Problem

Emiliano Pérez-3
Hi,

I finally solved the problem (it wasn't a socket problem after all), the writeWait was working fine, the ERROR_BAD_COMMAND thing came from one of my test cases that tested if the socket was opening correctly. It seems that i opened and closed the socket so fast that a sending operation (sending the ACK command) was caught in the middle, hence when it tried to send writeWait to the socket, this socket was already closed, solved it with a "(Delay forSeconds: 1) wait." between the open and the close.

Martin: listeningSocket is in fact a normal UDP socket and broadcastingSocket is a socket handled by the Broadcast strategy, it can be either a multicast strategy or a UDP broadcast strategy. All this works fine but now you mention it, i think it might need a little name refactoring.

Thanks for the help.

2006/11/24, Martin Kobetic <[hidden email]>:
Actually, maybe few notes. You're using terms like listeningSocket, broadcastingSocket and using multicast join: as well, so I'm wondering if there's some confusion here. Listening here seems to refer to normal UDP socket. The broadcasting socket seems to be a multicasting socket actually, however it all depends on the actual IP addresses you're using. Broadcasting address is usually the last address in your network address space ( e.g. 192.168.1.255/24) and there's no joining or leaving. Everybody can listen in on those messages. Multicasting addresses are from the dedicated range 224... - 23?... (I don't remember the upper limit) and you need to explicitly join: and leave: a specific address. Anyway, I wonder if you've got all that lined up properly.

HTH,

Martin

Emiliano Pérez wrote:
> Hi, it´s me again, i´m still getting the problem. I´ve tried different
> solutions, and it still doesn´t works.
>
> a little more info:
>

> This is the p2p sending code:
>
>    sendPeerCommand: aCommand to: aPeerAddress
>        self listeningSocket writeWait.
>        self listeningSocket sendTo: aPeerAddress buffer: (aCommand
> encodeCommand).
>
> - if i put the writeWait before sending it gives me the
> ERROR_BAD_COMMAND from the primitive 685 coming from the writeWait.
> - if i don´t put it, it gives me the BADARGS_ERROR in the primitive 676
> coming from the sendTo:buffer: message.
>
> I emphasize the fact that the error appears only when sending an
> Acknowledgment, in other words it´s the executeOn: from a received
> command who calls the sendPeerCommand message.
>
> Any help on the "why" or the "how" of this 2 errors wold be very
> appreciated too.
> Thanks,
> Emiliano.
>
> Emiliano Pérez escribió:
>> Hello, this is my first post in this list, I´m Emiliano Pérez.
>>
>> I´m working on an service that is meant to discover other machines in
>> the LAN running the same service. This is done by an object running 2
>> threads, the first has a receiving socket on regular udp. and the
>> other has a receiving multicast (managed as a strategy) socket. The
>> broadcast socket is for detecting the other machines, and the udp
>> socket is for pear to pear communication. The sockets receive commands
>> and send acknowledgments. When i start the object it sends an "enter
>> command" to the multicast ip, so the others can "see" it and send him
>> an acknowledgment through the p2p socket. The problem comes up when
>> the local object receives an "Enter" command from himself and sends an
>> Acknowledge command to the sender (self) . When it sends that last
>> command it keeps getting a BADARGS_ERROR exception from the p2p
>> socket. To explain a little more what it is that i do i copy some
>> methods below that i hope, will help you to understand.
>> The code:
>>
>> " - the start method "
>>
>> ->start
>>    self isActive ifFalse:[
>>                            self prepareSocketAt: self listeningPort.
>>             " newUDPserverAtPort:xxxx "
>>                            self broadcastingStrategy open.

>>              " in this case a multicast socket "
>>                            self turnOn.
>>              " this method sets isActive in true "
>>                            self launchPeerThread.
>>                            self launchBroadcastingThread.
>>                            self
>> advertise.].                                       "
>> sendBroadcastCommand: EnterCommand "
>>
>> ->launchPeerThread
>>        [
>>        [self isActive] whileTrue:[ | cmd |
>>                                cmd:=self receivePeerCommand.
>>                                cmd executeOn: self.
>>                                ].
>>        self broadcastingStrategy close.] fork.
>>
>> " - the broadcast thread is the same, only receiveBroadcastCommand
>> instead of receiveBroadcastCommand ".
>>
>>
>> ->receivePeerCommand
>>
>>        | peerAddress buffer size |             buffer:=ByteArray new:
>> self defaultBufferSize.
>>        peerAddress:=IPSocketAddress new.
>>        self listeningSocket readWait.
>>        size:=self listeningSocket receiveFrom: peerAddress buffer:
>> buffer start: 1 for: buffer size.
>>        ^DiscovererCommand decodeFrom: (buffer copyFrom: 1 to: size).
>>
>> MulticastStrategy->receiveBroadcast
>>
>>    | buffer size |
>>
>>    buffer := ByteArray new: self defaultBufferSize.
>>    self broadcastingSocket readWait.
>>    size := self broadcastingSocket receiveFrom: self
>> inBroadcastingAddress
>>                buffer: buffer.
>>    ^buffer copyFrom: 1 to: size
>>
>> " this is the code that starts the multicast socket "
>>
>> MulticastStrategy->open
>>
>>    self broadcastingSocket: (SocketAccessor family: SocketAccessor
>> AF_INET
>>                type: SocketAccessor SOCK_DGRAM).
>>    self broadcastingSocket soReuseaddr: true.
>>    self broadcastingSocket bindTo: self inBroadcastingAddress.
>>    self broadcastingSocket
>>        join: (self multicastRequestFrom: self broadcastingGroup)
>>
>>
>> " this is the code that is executed when the command is received "
>>
>> EnterCommand->doExecuteOn: aReceiver
>>        aReceiver addHost: self senderAddress.
>>        aReceiver sendAcknowledgeTo: self senderAddress.
>>
>>
>> Thats the important code until i´m able to isolate the problem a bit
>> more. The error is not constant, but it appears about 60% of the times
>> when i start the object.
>>
>> Thanks in advance,
>> Emiliano.
>>
>>
>
>