How to bind a listening socket to an address?

Ian Piumarta ian.piumarta at inria.fr
Mon Sep 1 19:41:02 UTC 2003


Andreas Raab <andreas.raab at gmx.de> wrote:
> > Total VM support code upheaval: 2 lines modified and 3 added.
> Let's do it. Any contrary opinions?

David Farber <dfarber at numenor.com> wrote:
> >Total VM support code upheaval: 2 lines modified and 3 added.
> Could we /please/ get this into the stock VMs?!

Markus Fritsche <Fritsche.Markus at gmx.net> wrote:
> I have to admit that I don't know how to do it - but if I knew it, I
> would do it immediately :-)

The required primitive is now in my 3.6-beta9 Unix VMs, source and
binaries, usual place.  (Sq-vm-powerpc.deb and Sq-full.dmg archives will
arrive in a little while: the first requires I reboot my Mac into Debian
and the latter requires 15 minutes of upload time on my DSL line.)

Attached: changesets for [Old]Socket (for some imagey person to look at
and fiddle with), SocketPlugin (for TPR's VMM plugins package), and a
one-liner diff to platforms/Cross/plugins/SocketPlugin.h (which I will
commit to SF within the next couple of hours, along with the Unix support
changes, unless JMM and/or AR asks me not to -- in any case, the extra
declaration doesn't hurt even if the function behind it is absent,
assuming your compiler and linker aren't totally broken).

It seems to work, although I could only test this code with OldSocket
using a modifed version of my Socket class>>remoteTestServerTCP method,
from local vs. remote telnet sessions... :(

(Read: Some tests/examples in this new-fangled Socket class would be a
Really Great Thing, g{uy,al}s, given that trivial mods of the old examples
methods don't seem to give good results).

Ian
-------------- next part --------------
*** SF/platforms/Cross/plugins/SocketPlugin/SocketPlugin.h	Tue Jan 29 06:19:04 2002
--- devel/platforms/Cross/plugins/SocketPlugin/SocketPlugin.h	Mon Sep  1 20:24:06 2003
***************
*** 47,52 ****
--- 47,53 ----
  	Note: If accept() calls are not supported simply make the calls fail
  	and the old connection style will be used */
  void	sqSocketListenOnPortBacklogSize(SocketPtr s, int port, int backlogSize);
+ void	sqSocketListenOnPortBacklogSizeInterface(SocketPtr s, int port, int backlogSize, int addr);
  void	sqSocketAcceptFromRecvBytesSendBytesSemaID(
  			SocketPtr s, SocketPtr serverSocket,
  			int recvBufSize, int sendBufSize, int semaIndex);
-------------- next part --------------
'From Squeak3.6beta of ''4 July 2003'' [latest update: #5373] on 1 September 2003 at 9:00:38 pm'!

!OldSocket methodsFor: 'connection open/close' stamp: 'ikp 9/1/2003 20:47'!
listenOn: portNumber backlogSize: backlog interface: ifAddr
	"Listen for a connection on the given port.
	If this method succeeds, #accept may be used to establish a new connection"
	| status |
	status _ self primSocketConnectionStatus: socketHandle.
	(status == Unconnected)
		ifFalse: [self error: 'Socket status must Unconnected before listening for a new connection'].
	self primSocket: socketHandle listenOn: portNumber backlogSize: backlog interface: ifAddr.
! !

!OldSocket methodsFor: 'primitives' stamp: 'ikp 9/1/2003 20:55'!
primSocket: aHandle listenOn: portNumber backlogSize: backlog interface: ifAddr
	"Primitive. Set up the socket to listen on the given port.
	Will be used in conjunction with #accept only."
	<primitive: 'primitiveSocketListenOnPortBacklogInterface' module: 'SocketPlugin'>
	self destroy. "Accept not supported so clean up"! !


!OldSocket class methodsFor: 'examples' stamp: 'ikp 9/1/2003 20:59'!
remoteTestServerTCP
	"See remoteTestClientTCP for instructions on running this method."
	"OldSocket remoteTestServerTCP"

	| socket client buffer n |
	Transcript show: 'initializing network ... '.
	Socket initializeNetwork.
	Transcript show:'ok';cr.
	socket _ OldSocket newTCP.
	socket
		listenOn: 54321
		backlogSize: 5
		interface: (NetNameResolver addressFromString: '127.0.0.1'). "or: 0.0.0.0"
	Transcript show: 'server endpoint created -- run client test in other image'; cr.
	buffer _ String new: 4000.
	socket waitForConnectionUntil: self standardDeadline.
	client _ socket accept.
	[client isConnected] whileTrue: [
		client dataAvailable ifTrue:
			[n _ client	receiveDataInto: buffer.
			client sendData: buffer count: n]].
	client closeAndDestroy.
	socket closeAndDestroy.
	Transcript cr; show: 'server endpoint destroyed'; cr.
	^socket! !


!Socket methodsFor: 'connection open/close' stamp: 'ikp 9/1/2003 20:32'!
listenOn: portNumber backlogSize: backlog interface: ifAddr
	"Listen for a connection on the given port.
	If this method succeeds, #accept may be used to establish a new connection"
	| status |
	status _ self primSocketConnectionStatus: socketHandle.
	(status == Unconnected)
		ifFalse: [InvalidSocketStatusException signal: 'Socket status must Unconnected before listening for a new connection'].
	self primSocket: socketHandle listenOn: portNumber backlogSize: backlog interface: ifAddr.
! !

!Socket methodsFor: 'primitives' stamp: 'ikp 9/1/2003 20:33'!
primSocket: aHandle listenOn: portNumber backlogSize: backlog interface: ifAddr
	"Primitive. Set up the socket to listen on the given port.
	Will be used in conjunction with #accept only."
	<primitive: 'primitiveSocketListenOnPortBacklogInterface' module: 'SocketPlugin'>
	self destroy. "Accept not supported so clean up"! !

-------------- next part --------------
'From Squeak3.6beta of ''4 July 2003'' [latest update: #5373] on 1 September 2003 at 9:00:34 pm'!

!SocketPlugin methodsFor: 'primitives' stamp: 'ikp 9/1/2003 20:21'!
primitiveSocket: socket listenOnPort: port backlogSize: backlog interface: ifAddr
	"Bind a socket to the given port and interface address with no more than backlog pending connections.  The socket can be UDP, in which case the backlog should be specified as zero."

	| s okToListen addr |
	self var: #s declareC: 'SocketPtr s'.
	self primitive: 'primitiveSocketListenOnPortBacklogInterface' parameters: #(#Oop #SmallInteger #SmallInteger #ByteArray).
	s _ self socketValueOf: socket.
	"If the security plugin can be loaded, use it to check for permission.
	If 
	not, assume it's ok"
	sCCLOPfn ~= 0
		ifTrue: [okToListen _ self cCode: ' ((int (*) (SocketPtr, int)) sCCLOPfn)(s, port)'.
			okToListen
				ifFalse: [^ interpreterProxy primitiveFail]].
	addr _ self netAddressToInt: (self cCoerce: ifAddr to: 'unsigned char *').
	self
		sqSocket: s
		ListenOnPort: port
		BacklogSize: backlog
		Interface: addr! !



More information about the Squeak-dev mailing list