Created
July 11, 2012 08:35
Minimum code for tcp server
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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