class CompareAndSwapRegister:
"CompareAndSwap class"
def __init__(self):
self.value = 0
def CompareAndSwap(self, oldval, newval):
presval = self.value
if (presval == oldval):
self.value = newval
return presval
def __str__(self):
return str(self.value)
import re
def lineCAS(reg, line):
pat = re.compile('\s*(\d+)\s+(\d+)\s*')
mat = pat.match(line)
if (mat == None):
return 'Bad Syntax'
else:
return (str(reg.CompareAndSwap(int(mat.group(1)), int(mat.group(2)))))
#! /usr/bin/python
from CompareAndSwap import CompareAndSwapRegister
from lineCAS import lineCAS
def stdinCAS():
x = CompareAndSwapRegister()
try:
while True:
line = raw_input()
print lineCAS(x, line)
except EOFError:
pass
if __name__ == "__main__":
stdinCAS()
#! /usr/bin/python
from CompareAndSwap import CompareAndSwapRegister
import re
def stdinCAS():
pat = re.compile('\s*(\d+)\s+(\d+)\s*')
reg = CompareAndSwapRegister()
try:
while True:
line = raw_input()
mat = pat.match(line)
if (mat == None):
print 'Bad Syntax'
else:
print (str(reg.CompareAndSwap(int(mat.group(1)),
int(mat.group(2)))))
except EOFError:
pass
if __name__ == "__main__":
stdinCAS()
#! /usr/bin/python
from CompareAndSwap import CompareAndSwapRegister
import re
import socket
def serverCAS():
pat = re.compile('^\s*(\d+)\s+(\d+)\s*\n$')
reg = CompareAndSwapRegister()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) ;
s.bind(('', 22222))
s.listen(1)
while True:
strm, addr = s.accept()
print "Connection from ", addr
line = strm.recv(1000)
while line:
print line,
mat = pat.match(line)
if (mat == None):
repl = 'Bad Syntax'
else:
repl = (str(reg.CompareAndSwap(int(mat.group(1)),
int(mat.group(2)))))
strm.send(repl+'\n\r')
line = strm.recv(1000)
strm.close()
except KeyboardInterrupt:
print 'Exiting'
s.close()
if __name__ == "__main__":
serverCAS()
#! /usr/bin/python
import socket
import sys
if len(sys.argv) == 4:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((sys.argv[1], 22222))
s.send(sys.argv[2] + ' ' + sys.argv[3] + '\n')
resp = s.recv(1000)
print resp,
s.close()
Try sending incomplete lines and multiple lines.
#! /usr/bin/python
import socket
import sys
if len(sys.argv) == 3:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((sys.argv[1], 22222))
s.send(sys.argv[2])
resp = s.recv(1000)
print resp,
s.close()
Break up the line. This should result in unpredictable output.
#! /usr/bin/python
import socket
import sys
if len(sys.argv) == 4:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((sys.argv[1], 22222))
s.send(sys.argv[2])
s.send(' ')
s.send(sys.argv[3])
s.send('\n')
resp = s.recv(1000)
print resp,
s.close()
Because TCP is stream oriented, there is a problem in reading line oriented input.
recv until it doesSocket
Socket makefile methodfile object
readlinewriteflushcloseThe server can only process one connection at a time.
Try out the following Python program.
import os pid = os.fork() print 'PID = ', pid print 'Hello world'
In the original Unix solution to this problem, which works well if the two connections are independent and requires shared memory if they don't, the following calls are used to create independent processes. This will be illustrated on the board.
forkdupcloseexitwaitshmxxx for share memoryFortunately, much of the hard work can be put off to a super server. For CGI scripts, the web server acts as a super server. RPC mechanisms also resemble super servers.
The bad solution is to use non-blocking socket and write busy-wait loops to test them.
The hard one-process solution is to use a blocking call that can wait
on several input sources simultaneously.
This one uses the poll system call
with can be used via the
Python select
module.
Here's the basic idea.
select to wait for I/O
accept to create a new communicating socketsend calls sends the entire buffer
And here's some examples.
The preferred modern solution is to use
threads with
Python's
threading module.
threading.Thread with keyword arugments
t = threading.Thread(target=HandleConnection, args=(reg,strm,addr,))t.start()Finally, due to the use of a Global Interpreter Lock (GIL) in the CPython and Ruby MRI interpreters, think hard before using threads for compute-bound computation in Python and Ruby.