Hello world/Web server: Difference between revisions
Added PicoLisp |
Added Perl implementation |
||
Line 107: | Line 107: | ||
} |
} |
||
}</lang> |
}</lang> |
||
=={{header|Perl}}== |
|||
<lang Perl>use Socket; |
|||
my $port = 8080; |
|||
my $protocol = getprotobyname( "tcp" ); |
|||
socket( SOCK, PF_INET, SOCK_STREAM, $protocol ) or die "couldn't open a socket: $!"; |
|||
# PF_INET to indicate that this socket will connect to the internet domain |
|||
# SOCK_STREAM indicates a TCP stream, SOCK_DGRAM would indicate UDP communication |
|||
setsockopt( SOCK, SOL_SOCKET, SO_REUSEADDR, 1 ) or die "couldn't set socket options: $!"; |
|||
# SOL_SOCKET to indicate that we are setting an option on the socket instead of the protocol |
|||
# mark the socket reusable |
|||
bind( SOCK, sockaddr_in($port, INADDR_ANY) ) or die "couldn't bind socket to port $port: $!"; |
|||
# bind our socket to $port, allowing any IP to connect |
|||
listen( SOCK, SOMAXCONN ) or die "couldn't listen to port $port: $!"; |
|||
# start listening for incoming connections |
|||
while( accept(CLIENT, SOCK) ){ |
|||
print CLIENT "Goodbye, world!"; |
|||
close CLIENT; |
|||
}</lang> |
|||
Various modules exist for using sockets, including the popular IO::Socket which provides a simpler and more friendly OO interface for the socket layer. I refrained from using this module in order to use only what is provided by the average default Perl installation. |
|||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
Revision as of 18:09, 1 July 2011
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
The browser is the new GUI!
Serve our standard text "Goodbye, World!" to http://localhost:8080/ so that it can be viewed with a web browser.
Starting a web browser or opening a new window with this URL is not part of the task. Also you do not need to bother serving proper HTML, as browsers generally do the right thing with simple text like this. Your program must however, start or implement a server that accepts multiple client connections and serves text as requested.
C
Well, this is, um, slightly longer than what other languages would be. <lang C>#include <stdio.h>
- include <stdlib.h>
- include <omp.h>
- include <unistd.h>
- include <sys/types.h>
- include <sys/socket.h>
- include <sys/wait.h>
- include <signal.h>
- include <netinet/in.h>
- include <netdb.h>
- include <arpa/inet.h>
- include <err.h>
char canned_response[] = "HTTP/1.1 200 OK\r\n" "Content-Type: text/html; charset=UTF-8\r\n\r\n" "<html><head><title>Goodbye, world!</title>" "<style>h1{font-size:4cm; color: red; text-shadow: .2cm .2cm black}</style>"
"</head><body>
Goodbye, world!
</body></html>\r\n";
void reap(int x) { while(waitpid(-1, 0, WNOHANG) > 0); }
int do_server_stuff() { int sock = socket(AF_INET, SOCK_STREAM, 0); int one = 1; int client_fd; socklen_t sin_len; struct sigaction sac; char msg_in[4096];
if (sock < 0) err(1, "can't open socket"); setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));
int port = 8080; struct sockaddr_in svr_addr, cli_addr; svr_addr.sin_family = AF_INET; svr_addr.sin_addr.s_addr = INADDR_ANY; svr_addr.sin_port = htons(port); if (bind(sock, (struct sockaddr *) &svr_addr, sizeof(svr_addr)) == -1) { close(sock); err(1, "Can't bind"); }
listen(sock, 5);
sac.sa_handler = reap; sigemptyset(&sac.sa_mask); sac.sa_flags = SA_RESTART; if (sigaction(SIGCHLD, &sac, 0) == -1) err(1, "can't install signal handler");
while (1) { client_fd = accept(sock, (struct sockaddr *) &cli_addr, &sin_len); if (client_fd == -1) { perror("Can't accept"); continue; } if (!fork()) { /* child here */ close(sock); if (read(client_fd, msg_in, 4096) == -1) { perror("read failure"); } write(client_fd, canned_response, sizeof(canned_response) - 1);/*-1:'\0'*/ close(client_fd); exit(0); }
printf("got connection\n"); close(client_fd); } }
int main() { do_server_stuff(); return 0; }</lang>
Go
<lang go>package main
import (
"http" "fmt"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { fmt.Fprintln(w, "Goodbye, World!") }) if err := http.ListenAndServe(":8080", nil); err != nil { fmt.Println(err) }
}</lang>
Perl
<lang Perl>use Socket;
my $port = 8080; my $protocol = getprotobyname( "tcp" );
socket( SOCK, PF_INET, SOCK_STREAM, $protocol ) or die "couldn't open a socket: $!";
# PF_INET to indicate that this socket will connect to the internet domain # SOCK_STREAM indicates a TCP stream, SOCK_DGRAM would indicate UDP communication
setsockopt( SOCK, SOL_SOCKET, SO_REUSEADDR, 1 ) or die "couldn't set socket options: $!";
# SOL_SOCKET to indicate that we are setting an option on the socket instead of the protocol # mark the socket reusable
bind( SOCK, sockaddr_in($port, INADDR_ANY) ) or die "couldn't bind socket to port $port: $!";
# bind our socket to $port, allowing any IP to connect
listen( SOCK, SOMAXCONN ) or die "couldn't listen to port $port: $!";
# start listening for incoming connections
while( accept(CLIENT, SOCK) ){
print CLIENT "Goodbye, world!"; close CLIENT;
}</lang>
Various modules exist for using sockets, including the popular IO::Socket which provides a simpler and more friendly OO interface for the socket layer. I refrained from using this module in order to use only what is provided by the average default Perl installation.
PicoLisp
Contents of the file "goodbye.l": <lang PicoLisp>(html 0 "Bye" NIL NIL
"Goodbye, World!" )</lang>
Start server:
$ pil @lib/http.l @lib/xhtml.l -'server 8080 "goodbye.l"' -wait