--- a/IPSocketAddress.st Mon Jul 04 06:51:02 2016 +0200
+++ b/IPSocketAddress.st Thu Jul 07 07:02:57 2016 +0200
@@ -1,5 +1,3 @@
-"{ Encoding: utf8 }"
-
"
COPYRIGHT (c) 1995 by Claus Gittinger
All Rights Reserved
@@ -562,7 +560,7 @@
!
isLocal
- "answer true, if this address adresses a peer on the same host"
+ "answer true, if this address addresses a peer on the same host"
^ (self at:5) == 127
--- a/IPv6SocketAddress.st Mon Jul 04 06:51:02 2016 +0200
+++ b/IPv6SocketAddress.st Thu Jul 07 07:02:57 2016 +0200
@@ -1,5 +1,3 @@
-"{ Encoding: utf8 }"
-
"
COPYRIGHT (c) 1999 by eXept Software AG
All Rights Reserved
@@ -97,7 +95,7 @@
^ NameLookupError raiseRequestWith:aString
errorString:' - bad address string'.
].
- "allow adresses formated like: '[2001:4dd0:ffa3::1]'"
+ "allow addresses formated like: '[2001:4dd0:ffa3::1]'"
components first first = $[ ifTrue:[
components at:1 put:(components first copyFrom:2).
components last last = $] ifTrue:[
@@ -373,7 +371,7 @@
!
isLocal
- "answer true, if this address adresses a peer on the same host: ::1/128"
+ "answer true, if this address addresses a peer on the same host: ::1/128"
^ (self at:9) == 0 and:[self hostAddress = self class local]
--- a/Socket.st Mon Jul 04 06:51:02 2016 +0200
+++ b/Socket.st Thu Jul 07 07:02:57 2016 +0200
@@ -237,7 +237,7 @@
More may be added in the future.
(the code is prepared for things like SNA or decNet;
however, right now, this code is empty and needs a little work.
- Implementing those is pretty straight forward, once the address
+ Implementing those is pretty straightforward, once the address
data structures are known.)
Due to historic reasons (I started this class, before I got hold of some
@@ -248,422 +248,422 @@
which are meant to be compatible to ST-80's UnixSocketAccessor interface.
TODO: cleanup historic leftovers,
- change to raise more signals on errors.
+ change to raise more signals on errors.
[author:]
- Claus Gittinger
+ Claus Gittinger
"
!
examples
"
example (get help info from an nntp server):
- [exBegin]
- |sock|
-
- sock := Socket newTCPclientToHost:'smtp.exept.de' port:'smtp'.
- sock isNil ifTrue:[
- self warn:'no smtp daemon is running'.
- ^ self
- ].
- Transcript showCR:sock nextLine.
-
- sock nextPutAll:'HELO STX socket test'; cr.
- Transcript showCR:sock nextLine.
- sock close
- [exEnd]
+ [exBegin]
+ |sock|
+
+ sock := Socket newTCPclientToHost:'smtp.exept.de' port:'smtp'.
+ sock isNil ifTrue:[
+ self warn:'no smtp daemon is running'.
+ ^ self
+ ].
+ Transcript showCR:sock nextLine.
+
+ sock nextPutAll:'HELO STX socket test'; cr.
+ Transcript showCR:sock nextLine.
+ sock close
+ [exEnd]
example (connect to finger daemon, get users entry):
- [exBegin]
- |sock entry|
-
- sock := Socket newTCPclientToHost:'localhost' port:'finger'.
- sock isNil ifTrue:[
- self warn:'no finger daemon is running'.
- ^ self
- ].
- sock useCRLF:true.
- sock buffered:false.
- sock isNil ifTrue:[
- Transcript showCR:'cannot connect to local finger daemon'
- ] ifFalse:[
- sock nextPutAll:(OperatingSystem getLoginName).
- sock cr.
-
- entry := sock nextLine.
- Transcript showCR:entry.
-
- sock close
- ]
- [exEnd]
+ [exBegin]
+ |sock entry|
+
+ sock := Socket newTCPclientToHost:'localhost' port:'finger'.
+ sock isNil ifTrue:[
+ self warn:'no finger daemon is running'.
+ ^ self
+ ].
+ sock useCRLF:true.
+ sock buffered:false.
+ sock isNil ifTrue:[
+ Transcript showCR:'cannot connect to local finger daemon'
+ ] ifFalse:[
+ sock nextPutAll:(OperatingSystem getLoginName).
+ sock cr.
+
+ entry := sock nextLine.
+ Transcript showCR:entry.
+
+ sock close
+ ]
+ [exEnd]
example (connect to an ftp server):
- [exBegin]
- |sock|
-
- sock := Socket newTCPclientToHost:'www.exept.de' port:'ftp'.
-
- sock buffered:false.
- Transcript showCR:sock nextLine.
- sock nextPutAll:('USER ' , 'anonymous'); cr.
- Transcript showCR:sock nextLine.
- sock nextPutAll:('PASS ' , 'fooBar'); cr.
- Transcript showCR:sock nextLine.
- sock nextPutAll:'HELP'; cr.
- [
- |line|
- line := sock nextLine.
- Transcript showCR:line.
- (line at:4) = $-
- ] whileTrue.
- sock close.
-
- 'dont know enough of the ftp protocol to continue here ...'
- [exEnd]
+ [exBegin]
+ |sock|
+
+ sock := Socket newTCPclientToHost:'www.exept.de' port:'ftp'.
+
+ sock buffered:false.
+ Transcript showCR:sock nextLine.
+ sock nextPutAll:('USER ' , 'anonymous'); cr.
+ Transcript showCR:sock nextLine.
+ sock nextPutAll:('PASS ' , 'fooBar'); cr.
+ Transcript showCR:sock nextLine.
+ sock nextPutAll:'HELP'; cr.
+ [
+ |line|
+ line := sock nextLine.
+ Transcript showCR:line.
+ (line at:4) = $-
+ ] whileTrue.
+ sock close.
+
+ 'dont know enough of the ftp protocol to continue here ...'
+ [exEnd]
example (connect to an snmp server [UDP]):
- Note: this is not a real connection, only the destination adress is
- being fixed.
- [exBegin]
- |sock port|
-
- sock := Socket newUDP.
- port := Socket portOfService:'snmp'.
- sock connectTo:'localhost' port:port.
- sock buffered:false.
- Transcript showCR:'got it'.
- sock close.
- [exEnd]
+ Note: this is not a real connection, only the destination address is
+ being fixed.
+ [exBegin]
+ |sock port|
+
+ sock := Socket newUDP.
+ port := Socket portOfService:'snmp'.
+ sock connectTo:'localhost' port:port.
+ sock buffered:false.
+ Transcript showCR:'got it'.
+ sock close.
+ [exEnd]
example (await connection from a client and read some data):
- [exBegin]
- |connectSock sock|
-
- connectSock := Socket newTCPserverAtPort:9998.
- connectSock isNil ifTrue:[
- Transcript showCR:'socket setup failed.'.
- ] ifFalse:[
- Transcript showCR:'listen ..'.
- (connectSock listenFor:5) ifFalse:[
- Transcript showCR:'listen failed.'.
- ] ifTrue:[
- Transcript showCR:'wait'.
- connectSock readWait.
- Transcript showCR:'accept'.
- sock := connectSock accept.
- sock isNil ifTrue:[
- Transcript showCR:'accept failed.'.
- ] ifFalse:[
- sock buffered:false.
- Transcript showCR:'server: got it'.
- 'can now do transfer via sock'.
- Transcript showCR:'read'.
- Transcript showCR:('got: ' , sock nextLine).
-
- Transcript showCR:'close'.
- sock close
- ].
- connectSock close.
- ]
- ]
- [exEnd]
+ [exBegin]
+ |connectSock sock|
+
+ connectSock := Socket newTCPserverAtPort:9998.
+ connectSock isNil ifTrue:[
+ Transcript showCR:'socket setup failed.'.
+ ] ifFalse:[
+ Transcript showCR:'listen ..'.
+ (connectSock listenFor:5) ifFalse:[
+ Transcript showCR:'listen failed.'.
+ ] ifTrue:[
+ Transcript showCR:'wait'.
+ connectSock readWait.
+ Transcript showCR:'accept'.
+ sock := connectSock accept.
+ sock isNil ifTrue:[
+ Transcript showCR:'accept failed.'.
+ ] ifFalse:[
+ sock buffered:false.
+ Transcript showCR:'server: got it'.
+ 'can now do transfer via sock'.
+ Transcript showCR:'read'.
+ Transcript showCR:('got: ' , sock nextLine).
+
+ Transcript showCR:'close'.
+ sock close
+ ].
+ connectSock close.
+ ]
+ ]
+ [exEnd]
example (connect to above server and send some data):
- [exBegin]
- |sock|
-
- sock := Socket newTCPclientToHost:'localhost' port:9998.
- sock isNil ifTrue:[
- Transcript showCR:'nope'
- ] ifFalse:[
- sock buffered:false.
- Transcript showCR:'client: got it'.
- 'can now do transfer via sock'.
- Transcript showCR:'sending <hello>'.
- sock nextPutLine:'hello'.
- sock close
- ]
- [exEnd]
+ [exBegin]
+ |sock|
+
+ sock := Socket newTCPclientToHost:'localhost' port:9998.
+ sock isNil ifTrue:[
+ Transcript showCR:'nope'
+ ] ifFalse:[
+ sock buffered:false.
+ Transcript showCR:'client: got it'.
+ 'can now do transfer via sock'.
+ Transcript showCR:'sending <hello>'.
+ sock nextPutLine:'hello'.
+ sock close
+ ]
+ [exEnd]
example: UNIX domain socket (await connection from a client and read some data):
- |connectSock sock|
-
- '/tmp/ud_socket' asFilename remove.
- connectSock := Socket newUNIXserverAt:'/tmp/ud_socket'.
- connectSock isNil ifTrue:[
- Transcript showCR:'socket setup failed.'.
- ] ifFalse:[
- Transcript showCR:'listen ..'.
- (connectSock listenFor:5) ifFalse:[
- Transcript showCR:'listen failed.'.
- ] ifTrue:[
- Transcript showCR:'wait'.
- connectSock buffered:false.
- connectSock readWait.
- Transcript showCR:'accept'.
- sock := connectSock accept.
- sock isNil ifTrue:[
- Transcript showCR:'accept failed.'.
- ] ifFalse:[
- sock buffered:false.
- Transcript showCR:'server: got it'.
- 'can now do transfer via sock'.
- Transcript showCR:'read'.
- Transcript showCR:('got: ' , sock nextLine).
-
- Transcript showCR:'close'.
- sock close
- ].
- connectSock close.
- ]
- ]
+ |connectSock sock|
+
+ '/tmp/ud_socket' asFilename remove.
+ connectSock := Socket newUNIXserverAt:'/tmp/ud_socket'.
+ connectSock isNil ifTrue:[
+ Transcript showCR:'socket setup failed.'.
+ ] ifFalse:[
+ Transcript showCR:'listen ..'.
+ (connectSock listenFor:5) ifFalse:[
+ Transcript showCR:'listen failed.'.
+ ] ifTrue:[
+ Transcript showCR:'wait'.
+ connectSock buffered:false.
+ connectSock readWait.
+ Transcript showCR:'accept'.
+ sock := connectSock accept.
+ sock isNil ifTrue:[
+ Transcript showCR:'accept failed.'.
+ ] ifFalse:[
+ sock buffered:false.
+ Transcript showCR:'server: got it'.
+ 'can now do transfer via sock'.
+ Transcript showCR:'read'.
+ Transcript showCR:('got: ' , sock nextLine).
+
+ Transcript showCR:'close'.
+ sock close
+ ].
+ connectSock close.
+ ]
+ ]
example (connect to above server and send some data;
- Notice, this fails, if above server code is executed in the same ST/X image
- (at least on LINUX), since the OS does not correctly handle
- a connect from within an interrupted accept system call
- On SGI's SVR4, this works ok
- [exBegin]
- |sock|
-
- sock := Socket newUNIXclientTo:'/tmp/ud_socket'.
- sock isNil ifTrue:[
- Transcript showCR:'nope'
- ] ifFalse:[
- sock buffered:false.
- Transcript showCR:'client: got it'.
- 'can now do transfer via sock'.
- Transcript showCR:'sending <hello>'.
- sock nextPutLine:'hello'.
- sock close
- ]
- [exEnd]
+ Notice, this fails, if above server code is executed in the same ST/X image
+ (at least on LINUX), since the OS does not correctly handle
+ a connect from within an interrupted accept system call
+ On SGI's SVR4, this works ok
+ [exBegin]
+ |sock|
+
+ sock := Socket newUNIXclientTo:'/tmp/ud_socket'.
+ sock isNil ifTrue:[
+ Transcript showCR:'nope'
+ ] ifFalse:[
+ sock buffered:false.
+ Transcript showCR:'client: got it'.
+ 'can now do transfer via sock'.
+ Transcript showCR:'sending <hello>'.
+ sock nextPutLine:'hello'.
+ sock close
+ ]
+ [exEnd]
example (UDP await packet from a client and read some data):
- [exBegin]
- |udpSock sock addr n dataBuffer|
-
- udpSock := Socket newUDPserverAtPort:9999.
- udpSock isNil ifTrue:[
- Transcript showCR:'socket setup failed.'.
- ] ifFalse:[
- Transcript showCR:'wait'.
- udpSock readWait.
-
- addr := IPSocketAddress new.
- dataBuffer := ByteArray new:1000.
- n := udpSock receiveFrom:addr buffer:dataBuffer start:1 for:dataBuffer size.
- n > 0 ifTrue:[
- Transcript showCR:('got: ' , n printString , 'bytes from ' , addr printString).
- Transcript showCR:('data: ' , (dataBuffer copyTo:n) printString).
- ] ifFalse:[
- Transcript showCR:'read failed'.
- ].
-
- Transcript showCR:'close'.
- udpSock close
- ]
- [exEnd]
+ [exBegin]
+ |udpSock sock addr n dataBuffer|
+
+ udpSock := Socket newUDPserverAtPort:9999.
+ udpSock isNil ifTrue:[
+ Transcript showCR:'socket setup failed.'.
+ ] ifFalse:[
+ Transcript showCR:'wait'.
+ udpSock readWait.
+
+ addr := IPSocketAddress new.
+ dataBuffer := ByteArray new:1000.
+ n := udpSock receiveFrom:addr buffer:dataBuffer start:1 for:dataBuffer size.
+ n > 0 ifTrue:[
+ Transcript showCR:('got: ' , n printString , 'bytes from ' , addr printString).
+ Transcript showCR:('data: ' , (dataBuffer copyTo:n) printString).
+ ] ifFalse:[
+ Transcript showCR:'read failed'.
+ ].
+
+ Transcript showCR:'close'.
+ udpSock close
+ ]
+ [exEnd]
example (connect to above UDP server and send some data;
- [exBegin]
- |sock|
-
- sock := Socket newUDP.
- sock isNil ifTrue:[
- Transcript showCR:'nope'
- ] ifFalse:[
- sock sendTo:(IPSocketAddress new hostName:'localhost' port:9999) buffer:'hello world'.
- sock close
- ]
- [exEnd]
+ [exBegin]
+ |sock|
+
+ sock := Socket newUDP.
+ sock isNil ifTrue:[
+ Transcript showCR:'nope'
+ ] ifFalse:[
+ sock sendTo:(IPSocketAddress new hostName:'localhost' port:9999) buffer:'hello world'.
+ sock close
+ ]
+ [exEnd]
example: pingWalk (try to ping hosts on the local network)
Note: it dosen't use ICMP ping, but tries to reache the echo service,
- which is disabled on most OS.
- [exBegin]
- |myAddress list top hosts walkProcess port|
-
- myAddress := OperatingSystem getNetworkAddresses
- keysAndValuesSelect:[:eachIFName :eachAddress|
- eachAddress isLocal not
- and:[eachIFName = 'wlan0']
- ].
- myAddress := myAddress first hostAddress.
-
- port := Socket portOfService:'echo'.
- port isNil ifTrue:[
- self error:'dont know echo port'.
- ^ self
- ].
-
- top := StandardSystemView new.
- top label:'PING net walk'.
-
- list := ScrollableView for:ListView in:top.
- list origin:0.0@0.0 corner:1.0@1.0.
-
- top openAndWait.
-
- walkProcess := [
- |l low hi direction tryHostID dottedName hostName conn addr|
-
- l := SortedCollection new.
-
- ' only works with type C-net
- the code below could simply do 1 to:254 do:[:hostID }
- but, to probe likely hosts earlier, the probing is done
- ping-pong like around my ip-address (assuming, that other machines
- have numbers around my own)'.
-
- low := hi := (myAddress at:4).
- direction := 1.
-
- [low > 0 or:[hi < 255]] whileTrue:[
- direction > 0 ifTrue:[
- hi := hi + 1.
- tryHostID := hi.
- direction := -1.
- ] ifFalse:[
- low := low - 1.
- tryHostID := low.
- direction := 1.
- ].
- (tryHostID between:1 and:254) ifTrue:[
- dottedName := (myAddress at:1) printString
- , '.' , (myAddress at:2) printString
- , '.' , (myAddress at:3) printString
- , '.' , tryHostID printString.
-
- top label:'PING net walk - trying ' , dottedName.
-
- top windowGroup withCursor:Cursor wait do:[
- conn := Socket newTCPclientToHost:dottedName port:port withTimeout:1000.
- conn notNil ifTrue:[
- addr := Socket ipAddressOfHost:dottedName.
- hostName := Socket hostWithIpAddress:addr.
- hostName isNil ifTrue:[
- hostName :='?'
- ].
- l add:(dottedName paddedTo:15 with:Character space)
- , ' '
- , (hostName paddedTo:15 with:Character space)
- , ' up & reachable'.
- list list:l.
- conn close.
- ]
- ].
- ].
- ].
- top label:'PING reachable hosts'.
- ] forkAt:(Processor userBackgroundPriority).
- walkProcess name:'ping net walker'.
- [exEnd]
-
-
- This example creates a simple UDP server that accepts
- single packets from anybody and broadcasts them to all
- clients that have connected so far.
-
- [exBegin]
- | socket address buffer msgSize clients |
- clients := Set new.
- address := IPSocketAddress new.
- buffer := String new: 1024.
-
- socket := self newUDPserverAtPort: 6666.
-
- Transcript showCR: 'server starting'.
-
- [
- [true] whileTrue: [
- (socket readWaitWithTimeoutMs: 200) ifFalse: [
- msgSize := socket
- receiveFrom: address
- buffer: buffer
- start: 1
- for: buffer size.
-
- clients add: address copy.
- clients do: [ :clientAddress |
- socket
- sendTo: clientAddress
- buffer: buffer
- start: 1
- for: msgSize]]
- ]
- ] ensure:[
- Transcript showCR: 'server shutting down'.
- socket close
- ]
- [exEnd]
+ which is disabled on most OS.
+ [exBegin]
+ |myAddress list top hosts walkProcess port|
+
+ myAddress := OperatingSystem getNetworkAddresses
+ keysAndValuesSelect:[:eachIFName :eachAddress|
+ eachAddress isLocal not
+ and:[eachIFName = 'wlan0']
+ ].
+ myAddress := myAddress first hostAddress.
+
+ port := Socket portOfService:'echo'.
+ port isNil ifTrue:[
+ self error:'dont know echo port'.
+ ^ self
+ ].
+
+ top := StandardSystemView new.
+ top label:'PING net walk'.
+
+ list := ScrollableView for:ListView in:top.
+ list origin:0.0@0.0 corner:1.0@1.0.
+
+ top openAndWait.
+
+ walkProcess := [
+ |l low hi direction tryHostID dottedName hostName conn addr|
+
+ l := SortedCollection new.
+
+ ' only works with type C-net
+ the code below could simply do 1 to:254 do:[:hostID }
+ but, to probe likely hosts earlier, the probing is done
+ ping-pong like around my ip-address (assuming, that other machines
+ have numbers around my own)'.
+
+ low := hi := (myAddress at:4).
+ direction := 1.
+
+ [low > 0 or:[hi < 255]] whileTrue:[
+ direction > 0 ifTrue:[
+ hi := hi + 1.
+ tryHostID := hi.
+ direction := -1.
+ ] ifFalse:[
+ low := low - 1.
+ tryHostID := low.
+ direction := 1.
+ ].
+ (tryHostID between:1 and:254) ifTrue:[
+ dottedName := (myAddress at:1) printString
+ , '.' , (myAddress at:2) printString
+ , '.' , (myAddress at:3) printString
+ , '.' , tryHostID printString.
+
+ top label:'PING net walk - trying ' , dottedName.
+
+ top windowGroup withCursor:Cursor wait do:[
+ conn := Socket newTCPclientToHost:dottedName port:port withTimeout:1000.
+ conn notNil ifTrue:[
+ addr := Socket ipAddressOfHost:dottedName.
+ hostName := Socket hostWithIpAddress:addr.
+ hostName isNil ifTrue:[
+ hostName :='?'
+ ].
+ l add:(dottedName paddedTo:15 with:Character space)
+ , ' '
+ , (hostName paddedTo:15 with:Character space)
+ , ' up & reachable'.
+ list list:l.
+ conn close.
+ ]
+ ].
+ ].
+ ].
+ top label:'PING reachable hosts'.
+ ] forkAt:(Processor userBackgroundPriority).
+ walkProcess name:'ping net walker'.
+ [exEnd]
+
+
+ This example creates a simple UDP server that accepts
+ single packets from anybody and broadcasts them to all
+ clients that have connected so far.
+
+ [exBegin]
+ | socket address buffer msgSize clients |
+ clients := Set new.
+ address := IPSocketAddress new.
+ buffer := String new: 1024.
+
+ socket := self newUDPserverAtPort: 6666.
+
+ Transcript showCR: 'server starting'.
+
+ [
+ [true] whileTrue: [
+ (socket readWaitWithTimeoutMs: 200) ifFalse: [
+ msgSize := socket
+ receiveFrom: address
+ buffer: buffer
+ start: 1
+ for: buffer size.
+
+ clients add: address copy.
+ clients do: [ :clientAddress |
+ socket
+ sendTo: clientAddress
+ buffer: buffer
+ start: 1
+ for: msgSize]]
+ ]
+ ] ensure:[
+ Transcript showCR: 'server shutting down'.
+ socket close
+ ]
+ [exEnd]
send a datagram to above server:
- [exBegin]
-
- | socket address buffer host msg |
-
- host := Dialog
- request: 'What is the name of the server''s host?'
- initialAnswer: 'localhost'.
-
- socket := self newUDP.
-
- address := IPSocketAddress hostName: host port: 6666.
-
- buffer := ByteArray new: 1000.
- [
- [(msg := Dialog request: 'Say something') isEmpty] whileFalse:[
- | replySize stream |
-
- socket writeWait.
- stream := buffer writeStream.
- stream nextPutAll: msg.
- socket sendTo:address buffer:buffer start:1 for:stream position.
- socket readWait.
-
- replySize := socket receiveFrom:address buffer:buffer.
- replySize > 0 ifTrue: [
- Transcript cr; nextPutAll: 'Server acknowledged: '.
- Transcript show: ((buffer copyFrom: 1 to: replySize) asString)
- ]
- ]
- ] ensure: [socket close].
- Transcript cr
- [exEnd]
+ [exBegin]
+
+ | socket address buffer host msg |
+
+ host := Dialog
+ request: 'What is the name of the server''s host?'
+ initialAnswer: 'localhost'.
+
+ socket := self newUDP.
+
+ address := IPSocketAddress hostName: host port: 6666.
+
+ buffer := ByteArray new: 1000.
+ [
+ [(msg := Dialog request: 'Say something') isEmpty] whileFalse:[
+ | replySize stream |
+
+ socket writeWait.
+ stream := buffer writeStream.
+ stream nextPutAll: msg.
+ socket sendTo:address buffer:buffer start:1 for:stream position.
+ socket readWait.
+
+ replySize := socket receiveFrom:address buffer:buffer.
+ replySize > 0 ifTrue: [
+ Transcript cr; nextPutAll: 'Server acknowledged: '.
+ Transcript show: ((buffer copyFrom: 1 to: replySize) asString)
+ ]
+ ]
+ ] ensure: [socket close].
+ Transcript cr
+ [exEnd]
loopBack:
- [exBegin]
-
- |readerTask readingSocket writingSocket|
-
- readingSocket := self newTCPserverAtPort:9999.
- readerTask :=
- [
- |connection|
-
- readingSocket listenFor:1.
- connection := readingSocket accept.
- readingSocket close.
- [connection atEnd] whileFalse:[
- Transcript showCR:(connection nextLine).
- ].
- connection close.
- ] fork.
-
- Delay waitForSeconds:1.
- writingSocket := self newTCPclientToHost:'localhost' port:9999.
- writingSocket nextPutLine:'Hello'.
- writingSocket nextPutLine:'World'.
- writingSocket close.
- [exEnd]
+ [exBegin]
+
+ |readerTask readingSocket writingSocket|
+
+ readingSocket := self newTCPserverAtPort:9999.
+ readerTask :=
+ [
+ |connection|
+
+ readingSocket listenFor:1.
+ connection := readingSocket accept.
+ readingSocket close.
+ [connection atEnd] whileFalse:[
+ Transcript showCR:(connection nextLine).
+ ].
+ connection close.
+ ] fork.
+
+ Delay waitForSeconds:1.
+ writingSocket := self newTCPclientToHost:'localhost' port:9999.
+ writingSocket nextPutLine:'Hello'.
+ writingSocket nextPutLine:'World'.
+ writingSocket close.
+ [exEnd]
"
! !
@@ -809,18 +809,18 @@
newTCPclientToHost:hostNameOrAddress port:aPortOrServiceName
"create a new TCP client socket connecting to a service.
- If hostNameOrAddress is a string, try all the resolved adresses regardless
- whether fpr IPv4 or IPv6.
+ If hostNameOrAddress is a string, try all the resolved addresses regardless
+ whether for IPv4 or IPv6.
Return a socket instance if ok, nil on failure.
Block until a connection is established (but only the current thread;
not the whole smalltalk).
See also: #newTCPclientToHost:port:withTimeout:"
^ self
- newTCPclientToHost:hostNameOrAddress
- port:aPortOrServiceName
- domain:nil
- withTimeout:nil
+ newTCPclientToHost:hostNameOrAddress
+ port:aPortOrServiceName
+ domain:nil
+ withTimeout:nil
"
Socket newTCPclientToHost:'www.exept.de' port:'http'
@@ -831,7 +831,7 @@
newTCPclientToHost:hostNameOrAddress port:aPortOrServiceName domain:aDomainSymbolOrNil withTimeout:millis
"create a new TCP client socket connecting to a service on hostNameOrAddress.
- If hostNameOrAddress is a string, try all the resolved adresses.
+ If hostNameOrAddress is a string, try all the resolved addresses.
Return a socket instance if ok, nil on failure.
Set aDomainSymbolOrNil to #AF_INET of #AF_INET6 to connect via a defined protocol.
Set aDomainSymbolOrNil to nil, to try all protocols.
@@ -841,34 +841,34 @@
|socket addressInfoList|
hostNameOrAddress isString ifFalse:[
- ^ self newTCPclientToAddress:hostNameOrAddress port:aPortOrServiceName withTimeout:millis.
+ ^ self newTCPclientToAddress:hostNameOrAddress port:aPortOrServiceName withTimeout:millis.
].
addressInfoList := SocketAddress
- getAddressInfo:hostNameOrAddress
- serviceName:aPortOrServiceName
- domain:aDomainSymbolOrNil
- type:#stream
- protocol:nil
- flags:0.
+ getAddressInfo:hostNameOrAddress
+ serviceName:aPortOrServiceName
+ domain:aDomainSymbolOrNil
+ type:#stream
+ protocol:nil
+ flags:0.
addressInfoList do:[:eachAddressInfo|
- |domainSymbol lastDomainSymbol|
-
- domainSymbol := eachAddressInfo domain.
- domainSymbol ~~ lastDomainSymbol ifTrue:[
- socket notNil ifTrue:[
- socket close.
- ].
- socket := self new domain:domainSymbol type:#stream.
- lastDomainSymbol := domainSymbol.
- ].
- (socket connectTo:eachAddressInfo socketAddress withTimeout:millis) ifTrue:[
- ^ socket.
- ].
+ |domainSymbol lastDomainSymbol|
+
+ domainSymbol := eachAddressInfo domain.
+ domainSymbol ~~ lastDomainSymbol ifTrue:[
+ socket notNil ifTrue:[
+ socket close.
+ ].
+ socket := self new domain:domainSymbol type:#stream.
+ lastDomainSymbol := domainSymbol.
+ ].
+ (socket connectTo:eachAddressInfo socketAddress withTimeout:millis) ifTrue:[
+ ^ socket.
+ ].
].
socket notNil ifTrue:[
- socket close.
+ socket close.
].
^ nil.
@@ -884,17 +884,17 @@
newTCPclientToHost:hostNameOrAddress port:aPortOrServiceName withTimeout:millis
"create a new TCP client socket connecting to a service on hostNameOrAddress.
- If hostNameOrAddress is a string, try all the resolved adresses regardless
- whether fpr IPv4 or IPv6.
+ If hostNameOrAddress is a string, try all the resolved addresses regardless
+ whether for IPv4 or IPv6.
Return a socket instance if ok, nil on failure.
If the millis arg is nonNil, stop trying to connect after that many milliseconds
and return nil."
^ self
- newTCPclientToHost:hostNameOrAddress
- port:aPortOrServiceName
- domain:self defaultIpDomainForConnect
- withTimeout:millis
+ newTCPclientToHost:hostNameOrAddress
+ port:aPortOrServiceName
+ domain:self defaultIpDomainForConnect
+ withTimeout:millis
!
newTCPserverAtAnonymousPort
@@ -4194,3 +4194,4 @@
version_CVS
^ '$Header$'
! !
+
--- a/SocketAddress.st Mon Jul 04 06:51:02 2016 +0200
+++ b/SocketAddress.st Thu Jul 07 07:02:57 2016 +0200
@@ -1,5 +1,3 @@
-"{ Encoding: utf8 }"
-
"
COPYRIGHT (c) 1995 by Claus Gittinger
All Rights Reserved
@@ -847,7 +845,7 @@
!
isLocal
- "answer true, if this address adresses a peer on the same host"
+ "answer true, if this address addresses a peer on the same host"
^ self subclassResponsibility
!
--- a/UDSocketAddress.st Mon Jul 04 06:51:02 2016 +0200
+++ b/UDSocketAddress.st Thu Jul 07 07:02:57 2016 +0200
@@ -1,5 +1,3 @@
-"{ Encoding: utf8 }"
-
"
COPYRIGHT (c) 1995 by Claus Gittinger
All Rights Reserved
@@ -190,7 +188,7 @@
!UDSocketAddress methodsFor:'testing'!
isLocal
- "answer true, if this address adresses a peer on the same host"
+ "answer true, if this address addresses a peer on the same host"
^ true
! !
@@ -198,10 +196,10 @@
!UDSocketAddress class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic2/UDSocketAddress.st,v 1.22 2015-03-02 23:21:26 stefan Exp $'
+ ^ '$Header$'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libbasic2/UDSocketAddress.st,v 1.22 2015-03-02 23:21:26 stefan Exp $'
+ ^ '$Header$'
! !
--- a/UnixPTYStream.st Mon Jul 04 06:51:02 2016 +0200
+++ b/UnixPTYStream.st Thu Jul 07 07:02:57 2016 +0200
@@ -92,17 +92,15 @@
pty := UnixPTYStream to:'ed'.
[
- pty readWait.
[pty atEnd] whileFalse:[
Transcript showCR:(pty nextLine).
- pty readWait.
].
pty close.
] forkAt:9.
- pty nextPutLine:'r Makefile'.
+ pty nextPutLine:'r Make.proto'.
pty nextPutLine:'1,2d'.
- pty nextPutLine:'$d'.
+ pty nextPutLine:'1,$s/#/+++++++/'.
pty nextPutLine:'w xxx'.
pty nextPutLine:'q'.
[exEnd]
@@ -113,12 +111,10 @@
[exBegin]
|pty password command|
- pty := UnixPTYStream to:'rlogin ' , OperatingSystem getHostName.
+ pty := UnixPTYStream to:'ssh 127.0.0.1'.
[
- pty readWait.
[pty atEnd] whileFalse:[
Transcript show:(pty next).
- pty readWait.
].
pty close.
] forkAt:9.
@@ -183,17 +179,16 @@
!UnixPTYStream methodsFor:'private'!
-openPTYFor:aCommandString withMode:mode inDirectory:aDirectrory
+openPTYFor:aCommandString withMode:openMode inDirectory:aDirectory
"open a pty to the unix command in commandString"
|blocked ptyFdArray execFdArray slaveFd masterFd shellAndArgs
- shellPath shellArgs mbx mbxName
- env shell args|
+ shellPath shellArgs mbx mbxName env|
handle notNil ifTrue:[
"the pipe was already open ...
this should (can) not happen."
- ^ self errorOpen
+ ^ self errorAlreadyOpen
].
lastErrorNumber := nil.
@@ -230,7 +225,7 @@
].
env := Dictionary new.
- env at:'TERM' put:'dumb'.
+ env at:'TERM' put:'dumb'.
env at:'SHELL' put:shellPath.
"/ must block here, to avoid races due to early finishing
@@ -247,7 +242,7 @@
fileDescriptors:execFdArray
fork:true
newPgrp:true
-"/ inDirectory:aDirectrory.
+ inDirectory:aDirectory.
]
action:[:status |
status stillAlive ifFalse:[
@@ -263,21 +258,16 @@
].
pid notNil ifTrue:[
- (OperatingSystem isMSWINDOWSlike) ifTrue:[
- self setFileDescriptor:masterFd mode:mode.
- "/ self setFileHandle:masterFd mode:mode
+ (OperatingSystem isVMSlike) ifTrue:[
+ "/
+ "/ reopen the mailbox as a file ...
+ "/
+ mbxName := OperatingSystem mailBoxNameOf:mbx.
+ mbxName notNil ifTrue:[
+ self open:mbxName withMode:openMode
+ ].
] ifFalse:[
- (OperatingSystem isVMSlike) ifTrue:[
- "/
- "/ reopen the mailbox as a file ...
- "/
- mbxName := OperatingSystem mailBoxNameOf:mbx.
- mbxName notNil ifTrue:[
- super open:mbxName withMode:mode
- ].
- ] ifFalse:[
- self setFileDescriptor:masterFd mode:mode.
- ]
+ self setFileHandle:masterFd mode:openMode.
]
] ifFalse:[
lastErrorNumber := OperatingSystem currentErrorNumber.
@@ -305,7 +295,6 @@
commandString := aCommandString.
buffered := false.
- position := 1.
hitEOF := false.
binary := false.
Lobby register:self.
@@ -342,5 +331,9 @@
version
^ '$Header$'
+!
+
+version_CVS
+ ^ '$Header$'
! !