The preamble to this post is that you can do this in a few lines with CURL, telnet, wget etc. I’m also sure someone has already written one of these but coming from a Java background, it was useful for me (and may be to others) to write a simple application that uses sockets in C.
very Simple HTTP Server Detector 1.0
(I was laughing when I wrote that title)
nobody@nobody:~/$ ./detect Usage: ./detect < domainname >
Output looks like this
nobody@nobody:~/$ ./detect www.microsoft.com Server: Microsoft-IIS/7.5 nobody@nobody:~/$ ./detect www.thexploit.com Server: Apache nobody@nobody:~/$ ./detect www.google.com Server: gws nobody@nobody:~/$ ./detect www.facebook.com Server: unknown nobody@nobody:~/$ ./detect www.reddit.com Server: AkamaiGHost nobody@nobody:~/$ ./detect www.twitter.com Server: hi <=== LOL!!
If you're new to C, see if you can come up with an implementation on your own and then check out the reference below (heavily commented for understanding):
/*
* Simple HTTP Server Detector
*
* Copyleft 2010.
* All rights have been wronged.
*
* Created on: Oct 5, 2010
* Author: xploit
*/
#include <stdio.h> /* Printf, perror, etc */
#include <stdlib.h> /* exit */
#include <sys/socket.h> /* sockets */
#include <netinet/in.h>
#include <netdb.h> /* Host lookup */
#include <string.h> /* bzero */
/* HTTP port */
#define WEB_PORT 80
/* Receive buffer size */
#define RECV_BUF 1024
/* Server buffer size */
#define SRVR_BUF 256
void fatal(char *error);
int main(int argc, char **argv) {
int socket_fd, i;
struct sockaddr_in remote_addr;
struct hostent *remote_host;
char recv_buf[RECV_BUF], srvr[SRVR_BUF];
if (argc < 2) {
printf("Usage: %s <domainname>n", argv[0]);
exit(1);
}
/* Create a socket */
if ((socket_fd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
fatal("Failed to create socketn");
}
/* Resolve the domain name */
if ((remote_host = gethostbyname(argv[1])) == NULL) {
fatal("Failed to resolve domain namen");
}
/* Set address and port of remote host */
memcpy(&(remote_addr.sin_addr), remote_host->h_addr_list[0],
remote_host->h_length);
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons(WEB_PORT);
/* Zero out the rest of the struct */
memset(&(remote_addr.sin_zero), 0, 8);
/* Connect to the domain */
if ((connect(socket_fd, (struct sockaddr *) &remote_addr,
sizeof(struct sockaddr))) == -1) {
fatal("Unable to connect to domainn");
}
/* Send a HTTP head req */
if ((send(socket_fd, "HEAD / HTTP/1.0rnrn", 19, 0)) == -1) {
fatal("Error sending HEAD requestn");
}
/* Receive the response */
if ((recv(socket_fd, &recv_buf, 1024, 0)) == -1) {
fatal("Error reading HEAD responsen");
}
/* Find the server substring */
char *srvr_ptr = strstr(recv_buf, "Server:");
/* Fail if it wasn't found */
if (srvr_ptr == NULL) {
fatal("Server: unknownn");
}
/* Read server line*/
i = 0;
while (srvr_ptr[i] != 'n' && i < SRVR_BUF) {
srvr[i] = srvr_ptr[i];
i++;
}
/* Terminate String */
srvr[i] = '\0';
/* Clear string */
srvr_ptr = NULL;
/* Print the results */
printf("%sn", srvr);
/* Stop both reception and transmission */
shutdown(socket_fd, 2);
return 0;
}
// Prints an error and exits
void fatal(char *error) {
printf(error);
exit(1);
}

Shouldn’t all of your send and recv calls be in a loop? I’m pretty sure there’s no guarantee that they will send or receive all that you request.
Oh really? See, I knew someone would tell me I did something wrong. I’m going to have to look into that.