Só que ao invés de fazer POG com memset, vamos usar uma função para setar dados para zero *bzero (). Uma função que escreve zeros para uma string. No nosso caso, serve para zerar o resto da struct.
void bzero (void *s, int n);
Pega os primeiros "n" bytes da string apontada em s e muda-os para zero.
listen() - esta função faz com que um socket aguarde por conexões.
Fica na escuta:
listen (socket, numero maximo de conexoes);
Ex.:
int sock2; sock2 = socket (AF_INET, SOCK_STREAM, 0);
listen (sock2, 4); // apenas 4 clients podem se conectar nesse socket.
write() - tambem é usada para enviar mensagens para um socket.
int write (socket, *buffer, tamanho utilizado do buffer);
write (sock, msg, strlen (msg));
Você pode substituir a função send() por write() dependendo do caso...
bind() - bind serve para unir um nome ao socket que você abriu. Para que fique bem claro, observe abaixo, IP do servidor: 201.34.36.133, IP do cliente: 201.45.44.144.
Para que o cliente localizado em 201.45.44.144 se comunique com um programa (servidor) localizado em 201.34.36.133 é necessário que os dois se comuniquem por um canal em comum, uma porta. Conexões telnet são feitas normalmente pela porta 23, ftp pela 21, http pela 80 etc. A diferenciação entre os tipos de serviço está pela porta que este abre. Então se eu for mandar uma mensagem para o servidor, esta tem que ir por uma porta aberta no sistema, específica para aquele programa servidor.
A função bind() faz o papel de abrir a porta no sistema.
A sintaxe da bind() é:
int bind (socket, estrutura de conexao (local), tamanho da estrutura);
accept() - estabelece conexões em um socket. Ela cria um novo socket com as mesmas propriedades do socket anterior do seu programa e aloca um novo "int socket" para a nova conexão.
int sock2,
newSock, // Este sera o novo socket
tamanho;
sock2 = socket (AF_INET, SOCK_STREAM, 0);
...
tamanho = sizeof (struct sockaddr);
listen (sock2, 3);
newSock = accept (sock2, (struct sockaddr_in *)&remote, &tamanho);
A sintaxe seria:
novo socket = accept (socket, estrutura de conexao, tamanho);
Paramos de conversa e vamos ao programa comentado:
#include "stdio.h"
#include "errno.h"
#include "sys/socket.h"
#include "resolv.h"
#include "arpa/inet.h"
#include "unistd.h"
#include "string.h"
#include "stdlib.h"
//nossa porta
#define PORT 666
int main (int argc, char *argv[]){
int serversock;
struct sockaddr_in self;
/* cria o socket */
serversock = socket (AF_INET, SOCK_STREAM, 0) ;
if ( serversock < 0 ){
perror("Erro no socket");
exit(1);
}
/* monta o endereço */
bzero (&self, sizeof(self));
self.sin_family = AF_INET;
self.sin_port = htons(PORT);
self.sin_addr.s_addr = INADDR_ANY; /* uso o endereço do host */
/* associa o endereço ao socket */
if ( bind (serversock, (struct sockaddr*)&self, sizeof(self)) ) {
perror("Erro no bind");
exit(1);
}
/* coloca o socket em escuta */
if ( listen (serversock, 20) ) {
perror("Erro no listen");
exit(1);
}
for(;;) {
int clientsock;
struct sockaddr_in client_addr;
int addrlen = sizeof (client_addr);
char * resposta ;
/* aguarda e aceita uma conexão externa */
clientsock = accept (serversock, (struct sockaddr*)&client_addr, &addrlen);
printf ("Client %s:%d connected\n",
inet_ntoa (client_addr.sin_addr),
ntohs (client_addr.sin_port));
/* envia uma resposta HTTP padrão */
<code>resposta = "HTTP/1.1 200 Ok\n\ncodigo em html\n" ;
write (clientsock, resposta, strlen (resposta));
/* fecha o socket da conexão recebida */
close (clientsock);
}
/* encerra o socket servidor */
close (serversock);
return 0;
}
Vamos lá, compile:
gcc -o code code.c; ./code
Feito isso, abra navegador na url http://localhost:666
BINGO!
Veja que o servidor é simples se agente usar netcat para conectar, por exemplo, o servidor responde do mesmo jeito, não usa uma regex ou parser para identificar apenas navegadores.
nc localhost 666
HTTP/1.1 200 Ok
Sua página HTML vai estar aqui.
Se não me engano o servidor Apache usa "pcre.h" para fazer estas regex de verificação... Bom, nosso servidor funcionou, voltando para o HTTP e estudando suas documentações podemos até fazer um post ou um get enviando dados, porém não é nosso objetivo aqui lidar com bots e spiders de web.
Se quiser aí vai o link para te ajudar nos spiders e entender HTTP, boa sorte:
Se conseguir mandar POST para um link usando "client" com socket, mande e-mail do seu programa em C para eu ver. ;)
Pulo do gato para o pessoal que não gosta de criar a roda, quer criar seus bots e spiders de forma portável, com estas bibliotecas você pode usar POST, GET e fazer AUTH, extrair links, tarefas no FTP, fazer downloads...
Vamos continuar estudando sockets a fundo e deixar as bibliotecas que usam sockets para depois.