ECHO! Echo! echo. (echo)

7

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.

Williham Totland

Posted 2016-04-27T10:00:14.433

Reputation: 1 186

Question was closed 2016-04-28T05:51:08.173

We require challenges to be self-contained, at the moment we have to read external resources to determine what we are supposed to do. Voting to close as unclear until you fix that. – Denker – 2016-04-27T10:59:57.820

@DenkerAffe: Addressed. – Williham Totland – 2016-04-27T11:23:10.757

2AKA: HTTP Cat program. – cat – 2016-04-27T12:39:50.950

Does not use library functions specifically designed to start and maintain an echo service? What? Seriously? – Bald Bantha – 2016-04-27T13:58:28.720

@epicTCK I'm not sure I understand your objection. – Williham Totland – 2016-04-27T14:01:26.283

2Infinity is , not ω – anatolyg – 2016-04-27T14:57:15.260

1@anatolyg isn't a number, ω is; and the score needs to be a number. – Williham Totland – 2016-04-27T15:03:03.817

4Why don't you just say if the program is invalid it's disqualified.. – Patrick Roberts – 2016-04-27T15:38:27.313

2I 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. – Digital Trauma – 2016-04-27T17:48:44.957

@DigitalTrauma, byte count. 7 is one byte. – Qwertiy – 2016-04-27T17:50:44.803

@DigitalTrauma, it's better to use fixed one-digit port as it voildn't affect program length. – Qwertiy – 2016-04-27T17:58:13.557

@Qwertiy which should be fine for just about any language that has a bind() equivalent, which I assume will be just about every entry. It just seemed a bit strange to explicitly state this as a rule (with such a harsh penalty)

– Digital Trauma – 2016-04-27T18:03:03.930

These penalties are ridiculous. If you want to require supporting both TCP and UDP, then just require it. With these harsh penalties, it's essentially required anyway in order to have a good score. – Mego – 2016-04-27T19:12:30.160

Why do you have the encoding rules? They seem pointless. – CalculatorFeline – 2016-04-27T20:25:18.640

1IPv4 or IPv6 protocols? Assuming IPv4. – Winny – 2016-04-27T23:43:53.107

I think at the core it's a fine challenge but the scoring is nonsensical. Typically either a solution is valid or it isn't; we don't really allow "almost correct" solutions in general. Also, the UTF-8 thing seems unnecessary to specify since by default we allow answers to be scored in bytes of whichever encoding is most natural. I recommend posting challenge ideas to the Sandbox where they can get feedback prior to going live.

– Alex A. – 2016-04-28T05:47:48.500

Answers

3

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.)

MayorMonty

Posted 2016-04-27T10:00:14.433

Reputation: 778

4

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

dieter

Posted 2016-04-27T10:00:14.433

Reputation: 2 010

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. – Morgan Thrapp – 2016-04-27T15:45:00.400

A UDP datagram may have up to 65,507 bytes, so 999 is not enough; I suggest 4**8. – Anders Kaseorg – 2016-04-27T16:00:04.110

well, afaik in practice the max size for udp packets is more around 500 bytes .. – dieter – 2016-04-27T16:03:22.377

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. – Anders Kaseorg – 2016-04-27T16:04:33.703

@Anders Karseorg And much more if you use https://en.wikipedia.org/wiki/IP_over_Avian_Carriers :) - anyway I put 4**8 and you give me an upvote, ok ?

– dieter – 2016-04-27T16:08:45.930

Also consider replacing while 1:c.send(c.recv(1)) with while c.send(c.recv(1)):1 to handle closed TCP connections without spinning forever. – Anders Kaseorg – 2016-04-27T16:12:25.987

3

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).

Winny

Posted 2016-04-27T10:00:14.433

Reputation: 1 120