[Pharo-project] Socket question (Was Re: Xtreams up to date)
I started looking at the Socket failures that I can reproduce and I can't wrap my head around the SocketReadingWritingTest>>setUp. Based on what I know about TCP sockets it doesn't make sense to me. AFAIK to get both ends of a connected TCP connection (lacking a socketpair call) I need 3 sockets. A listening socket, a client socket (doing connect) and finally the server socket that comes out as a result of accept on the listener. So I'd expect to see something like this in the setUp: | data input output listener socket1 socket2 process sync | Socket initializeNetwork. sync := Semaphore new. listener := Socket newTCP. listener listenOn: 9999. process := [ [ socket1 := listener accept ] ensure: [ listener close ]. sync signal ] fork. socket2 := Socket newTCP. socket2 connectTo: (NetNameResolver localHostAddress) port: 9999. sync wait. output := socket1 reading. input := socket2 writing. Surprisingly, the above doesn't work, while many of the Socket tests seem to pass for me despite my brain telling me that it can't possibly. Can anyone shed some light on this for me ? Thanks, Martin
Attached is some code I wrote a while ago based on advice that ConnectionQueue and SocketStream are correct starting points. I am a big believer that network code should do what it is told until it told to stop; timeouts should be in the hands of the user, application programmer or server administrator, not decided by the socket layer. ________________________________________ From: pharo-project-bounces@lists.gforge.inria.fr [pharo-project-bounces@lists.gforge.inria.fr] On Behalf Of mkobetic@gmail.com [mkobetic@gmail.com] Sent: Wednesday, January 12, 2011 1:13 PM To: pharo-project@lists.gforge.inria.fr Subject: [Pharo-project] Socket question (Was Re: Xtreams up to date) I started looking at the Socket failures that I can reproduce and I can't wrap my head around the SocketReadingWritingTest>>setUp. Based on what I know about TCP sockets it doesn't make sense to me. AFAIK to get both ends of a connected TCP connection (lacking a socketpair call) I need 3 sockets. A listening socket, a client socket (doing connect) and finally the server socket that comes out as a result of accept on the listener. So I'd expect to see something like this in the setUp: | data input output listener socket1 socket2 process sync | Socket initializeNetwork. sync := Semaphore new. listener := Socket newTCP. listener listenOn: 9999. process := [ [ socket1 := listener accept ] ensure: [ listener close ]. sync signal ] fork. socket2 := Socket newTCP. socket2 connectTo: (NetNameResolver localHostAddress) port: 9999. sync wait. output := socket1 reading. input := socket2 writing. Surprisingly, the above doesn't work, while many of the Socket tests seem to pass for me despite my brain telling me that it can't possibly. Can anyone shed some light on this for me ? Thanks, Martin
Martin did you check with squeak? because I have the impression that andreas fixed a bit some code. This is on our (igor) to do for 1.3 or 1.4 or 1.3 if somebody join and help. Noury and luc started to rewrite from scratch the sockets but I do not know the status. Stef On Jan 12, 2011, at 7:13 PM, mkobetic@gmail.com wrote:
I started looking at the Socket failures that I can reproduce and I can't wrap my head around the SocketReadingWritingTest>>setUp. Based on what I know about TCP sockets it doesn't make sense to me. AFAIK to get both ends of a connected TCP connection (lacking a socketpair call) I need 3 sockets. A listening socket, a client socket (doing connect) and finally the server socket that comes out as a result of accept on the listener. So I'd expect to see something like this in the setUp:
| data input output listener socket1 socket2 process sync | Socket initializeNetwork. sync := Semaphore new. listener := Socket newTCP. listener listenOn: 9999. process := [ [ socket1 := listener accept ] ensure: [ listener close ]. sync signal ] fork. socket2 := Socket newTCP. socket2 connectTo: (NetNameResolver localHostAddress) port: 9999. sync wait. output := socket1 reading. input := socket2 writing.
Surprisingly, the above doesn't work, while many of the Socket tests seem to pass for me despite my brain telling me that it can't possibly. Can anyone shed some light on this for me ?
Thanks,
Martin
Martin, On 12 Jan 2011, at 19:13, mkobetic@gmail.com wrote:
I started looking at the Socket failures that I can reproduce and I can't wrap my head around the SocketReadingWritingTest>>setUp. Based on what I know about TCP sockets it doesn't make sense to me. AFAIK to get both ends of a connected TCP connection (lacking a socketpair call) I need 3 sockets. A listening socket, a client socket (doing connect) and finally the server socket that comes out as a result of accept on the listener. So I'd expect to see something like this in the setUp:
| data input output listener socket1 socket2 process sync | Socket initializeNetwork. sync := Semaphore new. listener := Socket newTCP. listener listenOn: 9999. process := [ [ socket1 := listener accept ] ensure: [ listener close ]. sync signal ] fork. socket2 := Socket newTCP. socket2 connectTo: (NetNameResolver localHostAddress) port: 9999. sync wait. output := socket1 reading. input := socket2 writing.
Surprisingly, the above doesn't work, while many of the Socket tests seem to pass for me despite my brain telling me that it can't possibly. Can anyone shed some light on this for me ?
I have been playing around a little bit with your example and this works for me (Pharo 1.1.1 + Xtreams): | data input output listener socket1 socket2 process sync | data := #uninitialized. sync := Semaphore new. listener := Socket newTCP. listener listenOn: 9999 backlogSize: 10. process := [ [ socket1 := listener waitForAcceptFor: 10. socket1 waitForDataFor: 10. output := socket1 reading. data := output rest. sync signal ] ensure: [ listener close ] ] fork. socket2 := Socket newTCP. socket2 connectToHostNamed: 'localhost' port: 9999. input := socket2 writing. input write: 'Hello!'. sync wait. data asString Of course, you still have to close some sockets, but you get the idea. HTH, Sven PS: Yes, Socket (and friends) have some pretty confusing API, you have to stick to what you know that works ;-)
On Wed, 12 Jan 2011, mkobetic@gmail.com wrote:
I started looking at the Socket failures that I can reproduce and I can't wrap my head around the SocketReadingWritingTest>>setUp. Based on what I know about TCP sockets it doesn't make sense to me. AFAIK to get both ends of a connected TCP connection (lacking a socketpair call) I need 3 sockets. A listening socket, a client socket (doing connect) and finally the server socket that comes out as a result of accept on the listener. So I'd expect to see something like this in the setUp:
There's a way to use only 2 sockets and this causes the problem. If you use #listenOn:, then there will be no backlog and the listening socket will accept the connection. If you use #listenOn:backlogSize: instead, then it should work. Levente
| data input output listener socket1 socket2 process sync | Socket initializeNetwork. sync := Semaphore new. listener := Socket newTCP. listener listenOn: 9999. process := [ [ socket1 := listener accept ] ensure: [ listener close ]. sync signal ] fork. socket2 := Socket newTCP. socket2 connectTo: (NetNameResolver localHostAddress) port: 9999. sync wait. output := socket1 reading. input := socket2 writing.
Surprisingly, the above doesn't work, while many of the Socket tests seem to pass for me despite my brain telling me that it can't possibly. Can anyone shed some light on this for me ?
Thanks,
Martin
participants (5)
-
Levente Uzonyi -
mkobetic@gmail.com -
Schwab,Wilhelm K -
Stéphane Ducasse -
Sven Van Caekenberghe