Vamos usar algumas bibliotecas, são elas "sys/types.h","sys/sockets.h","netinet/in.h", "errno.h" e "netdb.h".
Outra função que vamos usar é a connect(). Seria uma função responsável pela conexão de seu socket cliente com um serviço servidor qualquer.
As headers necessárias para o uso dessa função são "sys/types.h" e "sys/socket.h".
Uma vez declaradas as headers, vamos declarar a função propriamente dita:
int connect(Meusocket,(struct sockaddr * )&server, sizeof(server));
read() - usada para ler mensagens enviadas de um socket. Sua sintaxe é igual a da função write():
int read (socket, *buffer, tamanho utilizado do buffer);
send() - usada para enviar uma mensagem para um socket.
int Send (socket, *mensagem, tamanho da mensagem, parametros adicionais)
Parâmetros adicionais podem ser:
#define MSG_OOB 0x1 /* process out-of-band data*/
#define MSG_DONTROUTE 0x4 /* bypass routing, usedirect interface */
#define MSG_DONTWAIT 0x40 /* don't block */
#define MSG_NOSIGNAL 0x2000 /* don't raise SIGPIPE */
- MSG_OOB - envia mensagens Out-Of-banda (OOB) - fora de banda - para sockets que suportam esse tipo de mensagem. Esse tipo de parâmetro é o calcanhar de aquiles do Windows 95, que trava com uma mensagem OOB (famoso winnuke).
- MSG_DONTROUTE - usado como debugador, para encontrar problemas.
- MSG_DONTWAIT - permite operações "non-blocking".
- MSG_NOSIGNAL - Ao mandar SIGPIPE em erros em sockets stream quando o outro endereço quebra a conexão.
Exemplo de utilização:
char cso [] = "sai fora cara"
send (newSock, cso, sizeof (cso), 0); //Sem parâmetros adicionais
Continuando...
Vou mostrar um exemplo de sockets usando protocolo HTTP com funções socket, connect, read e send. Vamos criar um simples cliente que lê uma source de uma página http, veja que antes de mandar para socket tenho que converter o HOST em IP.
/*
GarageCode coolest things Hehehe
http://GarageCode.tk
*Function this programm
This is Simples programm to splain the socket job in
http protocol,to send data and take request from WebServer
(C code with socket)
||
||
\ /
\/
[GET /index.html HTTP/1.1\nHost: www.site.com\t \n\n]
||
||
\ /
\/
(Apache listening server) if http read return the request with html to socket
this coolest to study sockets and http requests,in the future i make robot
about logic this code...
*tested with GCC
i wheel on Unix/Linux/BSD this:
gcc -o program program.c; ./program
Author: "Cooler_"
contact: tony.unix@yahoo.com.br or c00f3r@gmail.com
license: GPL2
visit this site: http://BotecoUnix.com.br
Real Geeks BotecoUnix
greetz
Thanks _mlk_ , m0nad,IAK,Fox,edenc,D3lf0,zepplin and f0kerdebug.
__ ____
/ /. .\
|--| 0 0 |
| | . . |
\ \____/
_----\___/---- _
/___\ /___\
| | |_|0|_| | |
| | |_|_|0| | | rick taylor from
| | |0|0|0| | | The Game SplatterHouse 2 at 1992
| | | /
\ ) -------- ( /
/\/ |) \/\
|/ \ |
( | )
|\ | /|
| | |
\ | /
\ ___ | ___ /
=o= | =o=
/xx | xx\ Code and art by Cooler_
(_______| |______)
*/
//libs diversas para tratar entrada, saida, memoria, string, erros...
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "errno.h"
#include "unistd.h"
//lib padrão para uso da socket
#include "netinet/in.h"
#include "arpa/inet.h"
#include "sys/types.h"
#include "sys/socket.h"
// lib para usar para converter host para ip
#include "netdb.h"
#define MAXSIZE 800
#define MAX 500
int main() {
int sockfd,n;
char *url,buff[MAXSIZE],sBuff[MAXSIZE],host[MAX],page[MAX],enter[MAX];
/*
no protocolo http o cliente manda dados com a info
GET /index.html HTTP/1.1
Host: www.site.com
para tal feito ficaria em C
GET /index.html HTTP/1.1\nHost: www.site.com\t \n\n
Peguei entrada um link http extraimos host e dados do GET
com sscanf,também pode ser feito com split ou regex,bom estraido
dados usei strcat para concatenar as variaveis alfanumericas
*/
char getpage[MAX]="GET /";
// struct do netdb para converter host para ip
struct hostent *ip;
// struct da socket
struct sockaddr_in end;
//pegamos entrada do usuario
printf("digite um link: ");
fgets(enter, sizeof(enter), stdin);
enter[strlen(enter)-1] = '\0';
//extraimos host e local da pagina
sscanf(enter, "http://%99[^/]/%99[^\n]", host, page);
printf("DNS = \"%s\"\n", host);
printf("Page = \"%s\"\n\n", page);
strcat(page," HTTP/1.1\nHost: ");
strcat(page,host);
strcat(page,"\t \n\n");
// função da lib netdb.h para converter ai nosso host para IP
ip = gethostbyname(host);
url=inet_ntoa(*(struct in_addr *)ip->h_addr);
strcat(getpage,page);
printf("%s",getpage);
/*
separamos buff para pegar resposta do server
mas antes preenchemos a memoria com \0
usamos sbuff para armazenar dados do envio
*/
memset(buff,'\0',sizeof(char)*MAXSIZE);
memset(sBuff,'\0',sizeof(char)*MAXSIZE);
strcpy(sBuff,getpage);
// condições simples em caso de erro
if( (sockfd=socket(AF_INET,SOCK_STREAM,0)) < 0 ){
perror("socket");
return errno;
}
// definimos a porta usado no caso 80
/*
sin familia
+ AF_INET (ARPA INTERNET PROTOCOLS) - "A mais usada"
+ AF_UNIX (UNIX INTERNET PROTOCOLS)
+ AF_ISO (ISO PROTOCOLS)
+ AF_NS (XEROX NETWORK SYSTEM PROTOCOLS)
*/
end.sin_family=AF_INET;
end.sin_port=htons(80);
/* Aqui é o seguinte:
htons significa "host to network short", como
é short trabalha com 2 bytes,mas ha ainda
outros tipos como: htonl("host to network
long",4 bytes), ntós("network to host
short",2 bytes), ntól("network to host
long", 4 bytes). */
if( inet_pton(AF_INET,url,&end.sin_addr) < 0){
perror("inet_pton");
return errno;
}
memset(end.sin_zero,'\0',8);
if(connect(sockfd,(struct sockaddr*)&end,sizeof(struct sockaddr)) < 0){
perror("connect");
return errno;
}
if( (send(sockfd, sBuff, strlen(sBuff), 0)) < 0){
perror("send");
close(sockfd);
return errno;
}
// recebe a resposta e mostra saida
while((n=read(sockfd,buff,MAXSIZE)) > 0) fprintf(stdout,"%s",buff);
close(sockfd);
return 0;
}
Compile:
gcc -o client client.c; ./client
Vai pedir um link, digite por exemplo http://www.botecounix.com.br/blog e veja que bacana.