7
\$\begingroup\$

Your challenge, should you choose to accept it, is simple:

Implement RFC 862, also known as the Echo Protocol:

The Echo protocol

An echo service simply sends back to the originating source any data it receives.

TCP Based Echo Service

One echo service is defined as a connection based application on TCP. A server listens for TCP connections on TCP port 7. Once a connection is established any data received is sent back. This continues until the calling user terminates the connection.

UDP Based Echo Service

Another echo service is defined as a datagram based application on UDP. A server listens for UDP datagrams on UDP port 7. When a datagram is received, the data from it is sent back in an answering datagram.

Scoring

  • The score is one point for every byte of code as encoded in UTF-8 or a language-specific code page, whichever is smaller.
  • If the program incompletely implements RFC 862 by providing only UDP or only TCP, the score is doubled.
  • If the program incorrectly implements RFC 862 by either using a port other than 7 or by dropping or transforming certain bytes due to language limitations or corner cutting, the score is quadrupled. (This stacks with the preceding point if applicable.)
  • If the program is invalid, the score is ω.

Rules

A valid program:

  • Does not use standard loopholes.
  • Per connection:
    • Accepts connections and receive incoming data.
    • Sends outgoing data in an amount that is always less than or equal to the amount of data received.
  • Does not invoke programs external to itself. (Spawning children to deal with multiple connections is fine, spinning up inetd or its local equivalent is not.)
  • Does not use library functions specifically designed to start and maintain an echo service.

This is code golf, so lowest score wins.

\$\endgroup\$

closed as unclear what you're asking by Ven, Rɪᴋᴇʀ, DJMcMayhem, Alex A. Apr 28 '16 at 5:51

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 2
    \$\begingroup\$ AKA: HTTP Cat program. \$\endgroup\$ – cat Apr 27 '16 at 12:39
  • 2
    \$\begingroup\$ Infinity is , not ω \$\endgroup\$ – anatolyg Apr 27 '16 at 14:57
  • 1
    \$\begingroup\$ @anatolyg isn't a number, ω is; and the score needs to be a number. \$\endgroup\$ – Williham Totland Apr 27 '16 at 15:03
  • 4
    \$\begingroup\$ Why don't you just say if the program is invalid it's disqualified.. \$\endgroup\$ – Patrick Roberts Apr 27 '16 at 15:38
  • 2
    \$\begingroup\$ I think the rule about port 7 is pointless. In general, you'll need to be root to use ports <1024, regardless of language. I assume that this challenge is allowing entries to run as root with no extra penalty. \$\endgroup\$ – Digital Trauma Apr 27 '16 at 17:48
3
\$\begingroup\$

JavaScript (Node.js) 102 Bytes (51 * 2)

require("net").createServer(s=>s.pipe(s)).listen(7)

You can add UDP for a total of 132 bytes, as seen below:

require("net").createServer(s=>s.pipe(s)).listen(7),(u=require("dgram").createSocket("udp4")).on("message",msg=>u.send(msg)).bind(7)

Was tested on node.js v5.2.0

Make sure to run with sudo on Unix descendants (OS X, Linux, etc.)

\$\endgroup\$
4
\$\begingroup\$

Python, 299 295 265 263

from threading import*
from socket import*
a='',7;S=socket
u=S(2,2);u.bind(a)
def U():
 while 1:u.sendto(*u.recvfrom(4**8))
Thread(None,U).start()
def C(c,x):
 while c.send(c.recv(1)):1
s=S(2,1);s.bind(a);s.listen(1)
while 1:Thread(None,C,args=s.accept()).start()

handles both udp and tcp.

@MorganThrapp helped saving 33 (!) chars

\$\endgroup\$
  • \$\begingroup\$ You can also get rid of the parens on ('',7). Also, move s=S(2,2);s.bind(a) out of U to save another byte. \$\endgroup\$ – Morgan Thrapp Apr 27 '16 at 15:45
  • \$\begingroup\$ A UDP datagram may have up to 65,507 bytes, so 999 is not enough; I suggest 4**8. \$\endgroup\$ – Anders Kaseorg Apr 27 '16 at 16:00
  • \$\begingroup\$ well, afaik in practice the max size for udp packets is more around 500 bytes .. \$\endgroup\$ – dieter Apr 27 '16 at 16:03
  • \$\begingroup\$ No, in practice it’s 1472 for non-fragmented datagrams (1500 ethernet MTU − 20 byte IP header − 8 byte UDP header), but fragmented datagrams or jumbograms can be larger. \$\endgroup\$ – Anders Kaseorg Apr 27 '16 at 16:04
  • \$\begingroup\$ @Anders Karseorg And much more if you use en.wikipedia.org/wiki/IP_over_Avian_Carriers :) - anyway I put 4**8 and you give me an upvote, ok ? \$\endgroup\$ – dieter Apr 27 '16 at 16:08
3
\$\begingroup\$

Racket, 231

(thread(λ()(do([l(tcp-listen 7)])(#f)(let-values([(i o)(tcp-accept l)])(copy-port i o)))))((λ(s b)(udp-bind! s #f 7)(do()(#f)(let-values([(n h p)(udp-receive! s b)])(udp-send-to s h p b 0 n))))(udp-open-socket)(make-bytes 65535))

TCP and UDP.

The TCP echo server uses a handy Racket procedure named copy-port that copies ports in the background, managed by Racket, instead of by the programmer. That also means I don't have to spin off a thread for each client, only for the listener (so I can start the UDP listener on the main thread).

\$\endgroup\$

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