# Jython example showing use of AF_INET sockets with SOCK_DGRAMs.
# Uses Jtux, a Java interface to POSIX/SUS (www.basepath.com/aup/jtux).
# System calls used: bind, close, _exit, fork, getaddrinfo,
# recvfrom, sendto, setsockopt, sleep, socket, waitpid
#
# By Marc Rochkind, jtux@basepath.com
# 11-July-2003
import jtux.UClock as UClock
import jtux.UConstant as UConstant
import jtux.UErrorException as UErrorException
import jtux.UFile as UFile
import jtux.UNetwork as UNetwork
import jtux.UProcess as UProcess
import jtux.UUtil as UUtil
import java.lang
import jarray
def b_to_s(ba): # convert byte array to string
s = ""
for b in ba:
if b == 0:
break
s += chr(b)
return s
nodename = "localhost"
servname1 = "5431" # unused port for peer 1
servname2 = "5432" # unused port for peer 2
msgsize = 300
hint = UNetwork.s_addrinfo()
hint.ai_family = UConstant.AF_INET
hint.ai_socktype = UConstant.SOCK_DGRAM
infop = UNetwork.AddrInfoListHead()
UNetwork.getaddrinfo(nodename, servname2, hint, infop)
sa_peer2 = infop.ai_next.ai_addr; # both peers need this socket addr
int_opt = UNetwork.SockOptValue_int() # Jtux's way of handling setsockopt values
int_opt.value = 1
pid = UProcess.fork()
if pid == 0: # Peer 1
msg = jarray.zeros(msgsize, 'b') # jarray is a standard Jython module
UNetwork.getaddrinfo(nodename, servname1, hint, infop)
sa_peer1 = infop.ai_next.ai_addr
UClock.sleep(1); # let peer 2 startup first -- not the best approach
fd_skt = UNetwork.socket(UConstant.AF_INET, UConstant.SOCK_DGRAM, 0)
UNetwork.setsockopt(fd_skt, UConstant.SOL_SOCKET, UConstant.SO_REUSEADDR,
int_opt, 0)
UNetwork.bind(fd_skt, sa_peer1, 0)
sa_sender = UNetwork.s_sockaddr_in()
sa_len = UUtil.IntHolder(); # Jtux class for passing ints by reference
maxmsgs = 4
for i in xrange(maxmsgs + 1):
if i == maxmsgs:
m = "Stop"
else:
m = "Message #" + str(i)
UNetwork.sendto(fd_skt, m, len(m), 0, sa_peer2, 0)
if i == maxmsgs:
break
nrcv = UNetwork.recvfrom(fd_skt, msg, len(msg), 0, sa_sender, sa_len)
print "Peer 1 got \"" + b_to_s(msg) + "\" from " + str(sa_sender)
UFile.close(fd_skt)
print "Peer 1 exiting"
UProcess._exit(UConstant.EXIT_SUCCESS)
else: # Peer 2
msg = jarray.zeros(msgsize, 'b') # jarray is a standard Jython module
fd_skt = UNetwork.socket(UConstant.AF_INET, UConstant.SOCK_DGRAM, 0)
UNetwork.setsockopt(fd_skt, UConstant.SOL_SOCKET, UConstant.SO_REUSEADDR, int_opt, 0)
UNetwork.bind(fd_skt, sa_peer2, 0)
sa_sender = UNetwork.s_sockaddr_in()
sa_len = UUtil.IntHolder()
while 1:
nrcv = UNetwork.recvfrom(fd_skt, msg, len(msg), 0, sa_sender, sa_len)
if b_to_s(msg[:4]) == "Stop":
break
print "Peer 2 got \"" + b_to_s(msg[:nrcv]) + "\" from " + str(sa_sender)
msg[0] = ord('m')
UNetwork.sendto(fd_skt, msg, len(msg), 0, sa_sender, sa_len.value)
UFile.close(fd_skt)
UProcess.waitpid(pid, None, 0)
print "Peer 2 exiting"
|