Skip to content

Instantly share code, notes, and snippets.

@kohyama
Created July 11, 2012 08:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kohyama/3089031 to your computer and use it in GitHub Desktop.
Save kohyama/3089031 to your computer and use it in GitHub Desktop.
Minimum code for tcp server
#include <sys/types.h> /* read */
#include <sys/socket.h> /* accept, bind, getsockname, listen, socket */
#include <sys/uio.h> /* read */
#include <sys/wait.h> /* waitpid */
#include <arpa/inet.h> /* htons */
#include <errno.h> /* errno */
#include <fcntl.h> /* open */
#include <signal.h> /* kill, sigaction */
#include <stdio.h> /* BUFSIZ */
#include <stdlib.h> /* daemon, exit */
#include <unistd.h> /* _exit, close, dup, fork, read, write */
static void
reapchild(int signo)
{
while (waitpid(-1, NULL, WNOHANG) > 0)
;
}
static void
parent_exit(int signo)
{
kill(0, SIGTERM);
exit(0);
}
static int
prog(int s)
{
int n;
char buf[BUFSIZ];
while (0 < (n = read(s, buf, BUFSIZ)))
write(s, buf, n);
}
int
main(int argc, char *argv[])
{
int addrlen, cs, pid, s;
struct sockaddr_in addr;
int port = 1111;
struct sigaction sa;
daemon(1, 1);
chdir("/");
close(0);
close(1);
close(2);
open("/dev/null", O_RDWR);
dup(0);
dup(0);
sa.sa_handler = reapchild;
sigaction(SIGCHLD, &sa, NULL);
sa.sa_handler = parent_exit;
sigaction(SIGTERM, &sa, NULL);
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
exit(1);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons((unsigned short)port);
addrlen = sizeof(addr);
if (bind(s, (struct sockaddr *)&addr, addrlen) < 0)
exit(1);
if (getsockname(s, (struct sockaddr *)&addr, &addrlen))
exit(1);
listen(s, 5);
for (; ; ) {
if ((cs = accept(s, (struct sockaddr *)&addr, &addrlen)) < 0) {
if (errno == EINTR)
continue;
exit(1);
}
switch (fork()) {
case -1:
exit(1);
case 0:
sa.sa_handler = SIG_DFL;
sigaction(SIGTERM, &sa, NULL);
close(s);
prog(cs);
_exit(0);
}
close(cs);
}
}
(use 'clojure.java.io)
(use 'server.socket)
(create-server 1234
(fn [in out]
(with-open [rdr (reader in) wtr (writer out)]
(doseq [line (line-seq rdr)]
(.write wtr (str "[" line "]\n"))
(.flush wtr)))))
; ----------------------------------------------------------------
; If you want to stop and restart a server instance from your code
; do like below:
(def ^:dynamic *server* (atom nil))
(defn start []
(reset! *server*
(create-server 1234
(fn [in out]
(with-open [rdr (reader in) wtr (writer out)]
(doseq [line (line-seq rdr)]
(.write wtr (str "[" line "]\n"))
(.flush wtr)))))))
(defn stop []
(when-not (nil? @*server*)
(close-server @*server*)
(reset! *server* nil)))
// for node.js
var net = require('net');
var server = net.createServer(function (stream) {
stream.on('data', function (data) { stream.write(data); });
stream.on('end', function () { stream.end(); }); });
server.listen(1111, 'localhost');
import SocketServer
class MyHandler(SocketServer.BaseRequestHandler):
def handle(self):
while True:
data = self.request.recv(1024)
if len(data) == 0:
self.request.close()
return
self.request.send(data)
if __name__ == "__main__":
HOST, PORT = "localhost", 1111
server = SocketServer.ThreadingTCPServer((HOST, PORT), MyHandler)
server.serve_forever()
require 'socket'
gs = TCPServer.open(1111)
addr = gs.addr
addr.shift
while true
Thread.start(gs.accept) do |cs|
while cs.gets
cs.write($_)
end
cs.close
end
end
(use gauche.net)
(set-signal-handler! SIGCHLD (lambda _
(guard (e ((<system-error> e)))
(while (< 0 (sys-waitpid -1))))))
(set-signal-handler! SIGTERM (lambda _ (sys-kill 0 SIGTERM)))
(define (daemon)
(when (positive? (sys-fork))
(sys-exit 0))
(sys-setsid)
(sys-chdir "/")
(sys-umask 0)
(call-with-input-file "/dev/null"
(cut port-fd-dup! (standard-input-port) <> ))
(call-with-output-file "/dev/null"
(lambda (out)
(port-fd-dup! (standard-output-port) out)
(port-fd-dup! (standard-error-port) out))))
(define (prog cs)
(let ((iport (socket-input-port cs))
(oport (socket-output-port cs)))
(let loop ((line (read-line iport)))
(cond
((eof-object? line) (socket-close cs))
(else
(display (string-append line "\r\n") oport)
(loop (read-line iport)))))))
(define (main args)
(daemon)
(let1 s (make-server-socket 'inet 1111 :reuse-addr? #t)
(let loop ((cs (socket-accept s)))
(let ((pid (sys-fork)))
(cond
((= pid 0) ; child
(set-signal-handler! SIGTERM #t) ; reset
(prog cs)
(sys-exit 0))
(else ; parent
(socket-close cs)
(loop (socket-accept s))))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment