tim Rowledge uploaded a new version of Network to project The Trunk: http://source.squeak.org/trunk/Network-tpr.281.mcz
==================== Summary ====================
Name: Network-tpr.281 Author: tpr Time: 6 July 2023, 4:47:54.419547 pm UUID: 72a96109-ef1b-435a-91ad-20428e13d2d9 Ancestors: Network-tpr.280
Add some more commentary to more Socket examples/tests, plus find ncat simulation commands that can allow testing to suceed. It would be nice if we could get those services runing on squeak.org
=============== Diff against Network-ct.279 ===============
Item was changed: ----- Method: Socket class>>ping: (in category 'utilities') ----- ping: hostName + "kinda-Ping the given host. Useful for checking network connectivity. + The host *must* be running a TCP echo server - note that these days very few actually do so and thus you may need to install one. Fortunately this is usually fairly simple; on a Ubuntu type linux system + sudo apt install ncat + sudo ncat -l 7 --keep-open --exec '/bin/cat' + ... ought to work. Ctrl-c to kill the ersatz echoserver when you are done testing. + + The ping command in a terminal uses a completely different protocol involving ICMP sockets and sacrifices to the Moon etc." + - "Ping the given host. Useful for checking network connectivity. The host must be running a TCP echo server." "Socket ping: 'squeak.cs.uiuc.edu'"
| tcpPort sock serverAddr startTime echoTime | tcpPort := 7. "7 = echo port, 13 = time port, 19 = character generator port"
serverAddr := NetNameResolver addressForName: hostName timeout: 10. serverAddr ifNil: [ ^self inform: 'Could not find an address for ', hostName ].
sock := Socket new. sock connectNonBlockingTo: serverAddr port: tcpPort. [sock waitForConnectionFor: 10] on: ConnectionTimedOut do: [:ex | (self confirm: 'Continue to wait for connection to ', hostName, '?') ifTrue: [ex retry] ifFalse: [ sock destroy. ^ self]].
sock sendData: 'echo!!'. startTime := Time millisecondClockValue. [sock waitForDataFor: 15] on: ConnectionTimedOut do: [:ex | (self confirm: 'Packet sent but no echo yet; keep waiting?') ifTrue: [ex retry]]. echoTime := Time millisecondClockValue - startTime.
sock destroy. self inform: hostName, ' responded in ', echoTime printString, ' milliseconds'. !
Item was changed: ----- Method: Socket class>>pingPorts:on:timeOutSecs: (in category 'utilities') ----- pingPorts: portList on: hostName timeOutSecs: timeOutSecs + "Attempt to connect to each of the given sockets on the given host. Wait at most timeOutSecs for the connections to be established. Answer an array of strings indicating the available ports. + Remember that the host must actually be running the relevant services for this to do anything useful; for example the port 7 echo is usually not installed on most modern unix servers. See also the #ping: method" - "Attempt to connect to each of the given sockets on the given host. Wait at most timeOutSecs for the connections to be established. Answer an array of strings indicating the available ports."
"Socket pingPorts: #(7 13 19 21 23 25 80 110 119) on: 'squeak.org' timeOutSecs: 15"
| serverAddr sockets startTime timeoutMsecs done result unconnectedCount connectedCount waitingCount | serverAddr := NetNameResolver addressForName: hostName timeout: 10. serverAddr ifNil: [ self inform: 'Could not find an address for ' , hostName. ^ #() ]. sockets := portList collect: [ :portNum | | sock | sock := Socket new. [ sock connectTo: serverAddr port: portNum ] on: ConnectionTimedOut do: [ ]. sock ]. startTime := Time millisecondClockValue. timeoutMsecs := (1000 * timeOutSecs) truncated. done := false. [ done ] whileFalse: [ unconnectedCount := 0. connectedCount := 0. waitingCount := 0. sockets do: [ :s | s isUnconnectedOrInvalid ifTrue: [ unconnectedCount := unconnectedCount + 1 ] ifFalse: [ s isConnected ifTrue: [ connectedCount := connectedCount + 1 ]. s isWaitingForConnection ifTrue: [ waitingCount := waitingCount + 1 ] ] ]. waitingCount = 0 ifTrue: [ done := true ]. connectedCount = sockets size ifTrue: [ done := true ]. (Time millisecondsSince: startTime) >= timeoutMsecs ifTrue: [ done := true ] ]. result := (sockets select: [ :s | s isConnected ]) collect: [ :s | self nameForWellKnownTCPPort: s remotePort ]. sockets do: [ :s | s destroy ]. ^ result!
Item was changed: ----- Method: Socket class>>pingPortsOn: (in category 'utilities') ----- pingPortsOn: hostName + "Attempt to connect to a set of well-known sockets on the given host, and answer the names of the available ports. + See also the comment for #ping: regarding server services. And also note that this is quite likely to seem like a port scanning attack to the server so be careful that it doesn't bite back" - "Attempt to connect to a set of well-known sockets on the given host, and answer the names of the available ports." "Socket pingPortsOn: 'www.disney.com'"
^ Socket pingPorts: #(7 13 19 21 23 25 80 110 119) on: hostName timeOutSecs: 20 !
Item was changed: ----- Method: Socket class>>sendTest (in category 'tests') ----- sendTest "Send data to the 'discard' socket of the given host. + Tests the speed of one-way data transfers across the network to the given host. + The host *must* be running a TCP discard server - note that these days very few actually do so and thus you may need to install one. Fortunately this is usually fairly simple; on a Ubuntu type linux system + sudo apt install ncat + sudo ncat -l --keep-open 9 --recv-only > /dev/null + ... ought to work. Ctrl-c to kill the ersatz server when you are done testing. " - Tests the speed of one-way data transfers across the - network to the given host. Note that most hosts - do not run a discard server."
"Socket sendTest"
| sock bytesToSend sendBuf bytesSent t serverName serverAddr | Transcript cr; show: 'starting send test'; cr. self initializeNetwork. serverName := UIManager default request: 'What is the destination server?' initialAnswer: 'create.ucsb.edu'. serverAddr := NetNameResolver addressForName: serverName timeout: 10. serverAddr = nil ifTrue: [^self inform: 'Could not find an address for ' , serverName]. sock := self new. Transcript show: '---------- Connecting ----------';cr. sock connectTo: serverAddr port: 9. sock isConnected ifFalse: [ sock destroy. ^self inform: 'could not connect']. Transcript show: 'connection established; sending data'; cr. bytesToSend := 1000000. sendBuf := String new: 64 * 1024 withAll: $x. bytesSent := 0. t := Time millisecondsToRun: [[bytesSent < bytesToSend] whileTrue: [sock sendDone ifTrue: [bytesSent := bytesSent + (sock sendSomeData: sendBuf)]]]. sock waitForSendDoneFor: self standardTimeout. sock destroy. Transcript show: '---------- Connection Closed ----------'; cr; show: 'send test done; time = ' , t printString; cr; show: (bytesToSend asFloat / t printShowingMaxDecimalPlaces: 2), ' * 1000 bytes/sec';cr;endEntry!
Item was changed: ----- Method: Socket class>>timeTest (in category 'examples') ----- timeTest + "Attempt to connect to an ntp server running a TCP 'daytime' service. Not all do, but as of 2023 the below nist server does. + The host *must* be running a TCP daytime server - note that these days very few actually do so and thus you may need to install one. Fortunately this is usually fairly simple; on a Ubuntu type linux system + sudo apt install ncat + sudo ncat -l 13 --keep-open --send-only --exec '/bin/date' + ... ought to work. Ctrl-c to kill the ersatz server when you are done testing. " "Socket timeTest"
| serverName serverAddr s | Transcript show: 'initializing network ... '. self initializeNetwork. Transcript show: 'ok'; cr. serverName := UIManager default request: 'What is your time server?' + initialAnswer: 'time.nist.gov'. - initialAnswer: 'localhost'. serverName isEmpty ifTrue: [^Transcript show: 'never mind'; cr]. serverAddr := NetNameResolver addressForName: serverName timeout: 10. serverAddr = nil ifTrue: [self error: 'Could not find the address for ' , serverName]. s := self new. Transcript show: '---------- Connecting ----------'; cr. s connectTo: serverAddr port: 13. "13 is the 'daytime' port number" s waitForConnectionUntil: (self deadlineSecs: 1). Transcript show: 'the time server reports: ' , s receiveData. s closeAndDestroy. Transcript show: '---------- Connection Closed ----------'; cr!
Item was changed: ----- Method: Socket class>>timeTestUDP (in category 'examples') ----- timeTestUDP + "Attempt to connect to an ntp server running a 'daytime' service via UDP. Not all do, including so far as we can tell, the time,nist.gov server that handles the #timeTest method. + The host *must* be running a UDP daytime server - note that these days very few actually do so and thus you may need to install one. Fortunately this is usually fairly simple; on a Ubuntu type linux system + sudo apt install ncat + sudo ncat -l 13 --keep-open --udp --send-only --exec '/bin/date' + ... ought to work. Ctrl-c to kill the ersatz server when you are done testing. " "Socket timeTestUDP"
| serverName serverAddr s | Transcript show: 'initializing network ... '. self initializeNetwork. Transcript show: 'ok'; cr. serverName := UIManager default request: 'What is your time server?' initialAnswer: 'localhost'. serverName isEmpty ifTrue: [^Transcript show: 'never mind'; cr]. serverAddr := NetNameResolver addressForName: serverName timeout: 10. serverAddr = nil ifTrue: [self error: 'Could not find the address for ' , serverName]. s := self newUDP. "a 'random' port number will be allocated by the system" "Send a packet to the daytime port and it will reply with the current date." Transcript show: '---------- Sending datagram from port ' , s port printString , ' ----------'; cr. s sendData: '!!' toHost: serverAddr port: 13. "13 is the daytime service" Transcript show: 'the time server reports: ' , s receiveData. s closeAndDestroy. Transcript show: '---------- Socket closed ----------'; cr!
packages@lists.squeakfoundation.org