108
\$\begingroup\$

Write a program or function that listens for incoming TCP traffic on port N. It offers a simple service: it calculates sum of IP address fields of incoming connection and returns.

Program or function reads integer N from arguments or stdin. It listens to incoming TCP connections on port N. When someone connects to that port, the program calculates sum of its IP address fields and sends it back to the client with trailing newline and closes connection.

  • Port number N is a valid port, and 210 < N < 215
  • Trailing newline can be either \nor \r\n
  • You can use either IPv4 or IPv6. Since IPv6 addresses are written in hexadecimal form, you must also provide result in same format, for example 2001:0db8:0000:0042:0000:8a2e:0370:7334 => 12ecd.

This is . Standard rules and loopholes apply.

Example

You run your server with ./server 1234. The server is now running and waiting for connections on port 1234. Then a client from 127.0.0.1 connects to your server. Your server performs a simple calculation: 127+0+0+1 => 128 and sends the result to the client (with trailing newline): 128\n. Then server closes connection and waits for next client.

Leaderboard

var QUESTION_ID=76379,OVERRIDE_USER=20569;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Is it allowed to use inetd/xinetd or similar? \$\endgroup\$ Mar 28, 2016 at 18:17
  • 94
    \$\begingroup\$ I like this, since it's a golfing challenge that golfing languages are unlikely to be very good at. \$\endgroup\$
    – isaacg
    Mar 28, 2016 at 18:54
  • 9
    \$\begingroup\$ Not only is it amazing that a TCP server is apparently a very easy program to write, I am thoroughly floored at the fact that it's getting golfed for fun. I'll just go back to struggling with FizzBuzz like an imbecile. \$\endgroup\$
    – MonkeyZeus
    Mar 29, 2016 at 19:50
  • 18
    \$\begingroup\$ @isaacg It's only time before someone finds the TCP server built-in in Mathematica \$\endgroup\$
    – Downgoat
    Mar 29, 2016 at 22:19
  • 3
    \$\begingroup\$ @MonkeyZeus To be fair, you will not see any good TCP server here. Making a reliable, scalable TCP server that handles all the intricacies of TCP (and your application protocol) well is a bit harder :D Though it certainly helps that the protocol is exceedingly simple - you don't even need to read the stream, something that I've seen broken in too many TCP servers to count :D \$\endgroup\$
    – Luaan
    Mar 30, 2016 at 9:11

40 Answers 40

1
2
2
\$\begingroup\$

Java, 283 275 bytes

Golfed

import java.net.*;class A{public static void main(String[] n)throws Exception{ServerSocket s=new ServerSocket(Integer.valueOf(n[0]));for(;;)try(Socket a=s.accept()){int v=0;for(byte b:a.getInetAddress().getAddress())v+=b&255;a.getOutputStream().write((v+"\n").getBytes());}}}

Ungolfed

import java.net.*;

class A {
public static void main(String[] n) throws Exception {
    ServerSocket s = new ServerSocket(Integer.valueOf(n[0]));
    for (;;)
        try (Socket a = s.accept()) {
            int v = 0;
            for (byte b : a.getInetAddress().getAddress())
                v += b & 255;
            a.getOutputStream().write((v + "\n").getBytes());
        }
}
}

Edit: Down to 274 thanks to @ogregoire

\$\endgroup\$
4
  • \$\begingroup\$ Much more elegant than mine. \$\endgroup\$ Mar 29, 2016 at 10:06
  • \$\begingroup\$ Use 255 instead of 0xff. Otherwise, same remarks as Matthew's answer. \$\endgroup\$ Mar 29, 2016 at 14:57
  • \$\begingroup\$ This isn't C. Java's main method is supposed to return void. \$\endgroup\$
    – SE is dead
    Jul 19, 2016 at 15:00
  • \$\begingroup\$ @dorukayhan indeed. Don't why I used int. Edited. \$\endgroup\$
    – ortis
    Jul 20, 2016 at 0:06
1
\$\begingroup\$

Matlab, 128 139 Bytes

Listens on port n, Ipv4 only (even if it listens on IPv6 too).

function m(n);while 1;t=tcpip('0.0.0.0',n,'NetworkRole','server');fopen(t);fprintf(t,'%d\n',sum(sscanf(t.RemoteHost,'%d.')));fclose(t);end
\$\endgroup\$
1
  • 2
    \$\begingroup\$ This doesn't take the listening port as input. \$\endgroup\$ Mar 30, 2016 at 12:32
1
\$\begingroup\$

k (55 characters)

This is essentially a translation of @h.j.k. solution in q with a couple of modifications.

."\\p ",*.z.x
.z.pg:{$+/0x0\:.z.a}
.z.ph:.h.hy[`].z.pg@

Usage: q filename.k PORT

\$\endgroup\$
1
\$\begingroup\$

AutoIT, 308 293 281 278 275 274 272 270 264 bytes

Func K($n)
TCPStartup()
$A=TCPListen("127.0.0.1",$n)
Do
$B=TCPAccept($A)
Until $B>0
While 1
$C=TCPRecv($B,$n)
If $C Then
$e=StringInStr($C,"st:")+4
$d=stringsplit(StringMid($C,$e,StringInStr($C,":")-$e),".")
ConsoleWrite($d[1]+$d[2]+$d[3]+$d[4])
EndIf
WEnd
EndFunc

Script-Example.com has an online compiler.

Reusing the port variable ($n) in the TCPRecv max-length parameter. Since it is never going to be less than 1024, it's saving me a byte.

\$\endgroup\$
1
\$\begingroup\$

Rust, 185 bytes

use std::{io::*,net::*};|a|while let Ok((mut a,SocketAddr::V6(b)))=TcpListener::bind(("::",a)).unwrap().accept(){write!(a,"{:x}
",b.ip().segments().map(|a|a as _).iter().sum::<u32>());}

This is a closure of type fn(u16). It accepts IPv6 connections and formats its output in hexadecimal. Golfing in Rust can be pretty challenging due to the number of transformations allowed by the compiler. Rust 1.55.0 or higher is necessary to compile this program.

\$\endgroup\$
0
\$\begingroup\$

LispyScript, 196 bytes

(->(require"http")(.createServer(function(q r)(r.end((str(-> (r.socket.remoteAddress)(.split".")(.map parseFloat)(.reduce (function(x y)(+ x y)))))'\n')(.listen(get 2 process.argv)"127.0.0.1"))))

If it looks like one of the Node submissions above, that's because it's pretty much just Node with a prettier face.

Ungolfed:

(->
  (require "http")
  (.createServer
    (function (request response)
      (response.writeHead 200 {'Content-Type': 'text/plain'})
      (response.end
        (str (-> (request.socket.remoteAddress)
             (.split ".")
             (.map parseFloat)
             (.reduce (function (x y) (+ x y)))))
          '\n')
  (.listen (|| (get 2 process.argv) 1337) "127.0.0.1"))))

Two functions, two method chains.

\$\endgroup\$
0
\$\begingroup\$

Common LIsp (Lispworks), 564 bytes

(require "comm")(defun make-stream-and-talk(handle)(let((stream(make-instance 'comm:socket-stream :socket handle :direction :io :element-type 'base-char)))(mp:process-run-function(format nil "" handle) '() 'f stream)))(defun f(stream)(unwind-protect(progn(multiple-value-bind(address port)(comm:socket-stream-address stream)(declare(ignore port))(format stream "~S"(reduce #'+(mapcar #'parse-integer(split-sequence "."(comm:ip-address-string address)))))(force-output stream))(close stream))))(comm:start-up-server :function 'make-stream-and-talk :service 10246)

ungolfed:

    (require "comm")
    (defun make-stream-and-talk (handle)
      (let ((stream (make-instance 'comm:socket-stream
                                   :socket handle
                                   :direction :io
                                   :element-type
                                   'base-char)))
        (mp:process-run-function (format nil ""
                                         handle)
                                 '()
                                 'f stream)))

    (defun f (stream)
      (unwind-protect
          (progn
            (multiple-value-bind (address port)
                (comm:socket-stream-address stream)
              (declare (ignore port))
              (format stream "~S" 
                      (reduce #'+
                              (mapcar #'parse-integer
                                      (split-sequence "."
                                                      (comm:ip-address-string address)))))
              (force-output stream))
            (close stream))))

    (comm:start-up-server :function 'make-stream-and-talk
                          :service 10246)

Usange:

    c:\~]$ telnet 127.0.0.1 10246


    Connecting to 127.0.0.1:10246...
    Connection established.
    To escape to local shell, press 'Ctrl+Alt+]'.
    you sent: 128
    Connection closed by foreign host.

    Disconnected from remote host(127.0.0.1:10246) at 23:42:56.

    Type `help' to learn how to use Xshell prompt.

Note:

reference Lispworks documents
\$\endgroup\$
0
\$\begingroup\$

Object Pascal, 342 340 bytes

A small (well the pascal definition of small...) server with the lowest level Sockets library. Listenes to IP4, port no. on the commandline.

uses sockets;var s,c,l,i,f:integer;a,b:TInetSockAddr;g:string;begin val(ParamStr(1),f,i);s:=fpSocket(2,1,0);a.sin_family:=2;a.sin_port:=ntobe(f);l:=sizeof(a);fpBind(s,@a,l);repeat fpListen(s,1);c:=fpaccept(s,@b,@l);f:=0;for i:=1to 4do f:=f+b.sin_addr.s_bytes[i];Str(f,g);g:=g+#10;fpsend(c,@g[1],length(g),0);fpshutdown(c,2);until False;end.

Ungolfed:

uses
  sockets;
var
  s, c, l, i, f: integer;
  a, b: TInetSockAddr;        { a=server, b=client }
  g: string;
begin
  val(ParamStr(1), f, i);     { store port no. in f }
  s := fpSocket(2, 1, 0);     { 2=AF_INET, 1=SOCK_STREAM, 0=PF_UNSPEC }
  a.sin_family := 2;          { 2=AF_INET }
  a.sin_port := ntobe(f);     { port to listen to, address initialized to localhost by default }
  l := sizeof(a);
  fpBind(s, @a, l);           { bind socket to address:port }
  repeat
    fpListen(s ,1);           { listen for one incoming connection }
    c := fpaccept(s, @b, @l); { accept connection, client address in b }
    f := 0;
    for i:=1 to 4 do
      f := f+b.sin_addr.s_bytes[i]; { add 4 bytes of client address }
    Str(f, g);                      { store f in a string }
    g := g+#10;                     { add newline }
    fpsend(c, @g[1], length(g), 0); { send the addition result }
    fpshutdown(c, 2);               { close the connection }
  until False;
end.
\$\endgroup\$
0
\$\begingroup\$

Racket, 174 bytes

(do([l(tcp-listen 1234)])(#f)(let*-values([(i o)(tcp-accept l)][(a b)(tcp-addresses i)])(displayln(for/sum([s(string-split b".")])(string->number s))o)(close-output-port o)))

Ungolfed

(do ([l (tcp-listen 1234)])
    (#f)
  (let*-values ([(i o) (tcp-accept l)]
                [(a b) (tcp-addresses i)])
    (displayln
     (for/sum ([s (string-split b ".")])
       (string->number s))
     o)
    (close-output-port o)))

Shoutout to cat for bringing the Racket competition!

\$\endgroup\$
0
\$\begingroup\$

NodeJS, (IPv4 and IPv6) 105 Bytes

require("net").createServer(s=>s.end(eval(s.remoteAddress.replace(/[:.]/g,"+"))).listen(process.argv[2])

Explanation:

require("net")               # TCP library
 .createServer(              # Create the server
   s=>                       # Socket is s
    s.end(                   # Print and end the connection
     eval(                   # Treat the following string like JavaScript
      s.remoteAddress        # The IP address (IPv4 or IPv6, depending on connection)
       .replace(/.|:/g, "+") # Replace all . and : with +
 )))                         # Close server response
 .listen(process.argv[2])    # Listen on the third index of the arg array (["node", "filename.js", "first arg"])
\$\endgroup\$
1
  • 1
    \$\begingroup\$ There is a missing parenthesis in the original code (not in the explanation) \$\endgroup\$
    – THC
    Jun 3, 2016 at 19:14
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.