Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
very simple TCP Echo server and client, with "strace"ing server thread : example #1.
/*
* (no copyright, license-free, AS-IS, for any commercial or oss or free source code)
*/
String host = args[0]
int port = args[1].toInteger()
int to_connect = 10 * 1000 // connect timeout in milli secs
int to_read = 10 * 1000 // read timeout in milli secs
SocketAddress sa_local = null // bind to system default address and port.
SocketAddress sa_remote = new InetSocketAddress(host, port)
Socket socket = new Socket()
socket.bind(sa_local)
println 'connect() start'
socket.connect(sa_remote, to_connect)
socket.setSoTimeout(to_read)
println 'SO_REUSEADDR = ' + socket.getReuseAddress()
println 'SO_LINGER = ' + socket.getSoLinger()
println 'SO_TIMEOUT = ' + socket.getSoTimeout()
println 'SO_KEEPALIVE = ' + socket.getKeepAlive()
println 'OOBINLINE = ' + socket.getOOBInline()
println 'TCP_NODELAY = ' + socket.getTcpNoDelay()
println 'connected to ' + sa_remote
InputStream sin = socket.inputStream
OutputStream sout = socket.outputStream
def c = System.console()
String senddata = c.readLine('send1>')
sout.write(senddata.bytes)
try {
int dummy = sin.read()
} catch (SocketTimeoutException toe) {
println 'read() timeout'
} catch (Exception e) {
e.printStackTrace()
}
senddata = c.readLine('send2>')
sout.write(senddata.bytes)
try {
int dummy = sin.read()
} catch (SocketTimeoutException toe) {
println 'read() timeout'
} catch (Exception e) {
e.printStackTrace()
}
c.readLine('shutdownInput?')
socket.shutdownInput()
c.readLine('shutdownOutput?')
socket.shutdownOutput()
c.readLine('close?')
socket.close()
/*
* ONLY work for Linux 2.6 (x86_64) (using syscall(2) from JNA)
* (no copyright, license-free, AS-IS, for any commercial or oss or free source code)
*/
@Grapes(
@Grab(group='net.java.dev.jna', module='jna', version='4.0.0')
)
import com.sun.jna.*
// {{{ syscall and strace utility
/** @see /usr/include/asm/unistd_64.h */
interface SYSCALL64 {
final int getpid = 39;
final int getppid = 110;
final int gettid = 186;
}
interface GLIBC extends Library {
int syscall(int number, Object... args);
}
class Strace {
static final GLIBC glibc = (GLIBC)Native.loadLibrary('c', GLIBC.class)
final int currentPid
final int currentPpid
final int currentTid
Strace() {
this.currentPid = glibc.syscall(SYSCALL64.getpid)
this.currentPpid = glibc.syscall(SYSCALL64.getppid)
this.currentTid = glibc.syscall(SYSCALL64.gettid)
}
void startMon(List<String> syscalls) {
Thread.start {
start(syscalls, System.out, System.err)
}
}
void startLog(List<String> syscalls) {
String ts = new Date().format('yyyy-MM-dd_HH-mm-ss')
String fname_sout = ts + '_' + currentTid + '.sout'
String fname_serr = ts + '_' + currentTid + '.serr'
println 'log stdout to ' + fname_sout
println 'log stderr to ' + fname_serr
OutputStream sout = new File(fname_sout).newOutputStream()
OutputStream serr = new File(fname_serr).newOutputStream()
Thread.start {
start(syscalls, sout, serr)
sout.close()
serr.close()
}
}
void start(List<String> syscalls, OutputStream sout, OutputStream serr) {
String syscalls_opts = ''
if (syscalls.size > 0) {
syscalls_opts = '-e trace=' + syscalls.join(',')
}
String command = 'strace ' + syscalls_opts + ' -p ' + currentTid
println 'start : ' + command
Process proc = command.execute()
proc.waitForProcessOutput(sout, serr)
int r = proc.exitValue()
sout.close()
serr.close()
println 'end : exitValue = ' + r
}
}
// }}}
List<String> syscalls = [
'socket', 'open', 'read', 'readv', 'recvfrom', 'write', 'writev', 'sendto', 'listen', 'bind', 'accept', 'shutdown', 'close']
syscalls -= 'read'
syscalls -= 'open'
Thread.start {
try {
int ECHO_PORT = 10007
ServerSocket serverSocket = null
Socket socket = null
InetAddress addrRemote = null
InetAddress addrLocal = null
def c = System.console()
//new Strace().startMon(syscalls)
new Strace().startLog(syscalls)
c.readLine('ready?')
serverSocket = new ServerSocket(ECHO_PORT);
println 'echo server started, listening port: ' + serverSocket.getLocalPort()
c.readLine('accpet?')
socket = serverSocket.accept()
adr = socket.getInetAddress()
adl = socket.getLocalAddress()
println 'Remote(' + adr.hostAddress + ':' + socket.port + ') -> Local(' + adl.hostAddress + ':' + socket.localPort + ')'
InputStream sin = socket.inputStream
OutputStream sout = socket.outputStream
try {
sin.eachByte(1024) { bytes, len ->
println 'read ' + len + ' bytes.'
c.readLine('echo?')
sout.write(bytes, 0, len)
}
} catch (IOException ioex) {
println 'closed from remote'
} finally {
try { sin.close() } catch (Exception ignore) {}
try { sout.close() } catch (Exception ignore) {}
}
c.readLine('close?')
serverSocket.close()
} catch (Exception e) {
e.printStackTrace()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment