Jump to content
Elf

Ajutor Winsock (C)

Recommended Posts

Bun, sa vedem ce se poate face.

Pe scurt, trebuie sa te conectezi pe portul 8081 (in cazul tau) prin TCP la acel host (127.0.0.1) si sa folosesti protocolul HTTP (versiunea 1.1) pentru a cere (GET) acea pagina.

Pentru inceput, conteaza daca programul este pentru Windows sau pentru Linux.

Pentru Windows, in primul rand, va trebui sa apelezi la inceput functia WSAStartUp() pentru initializarea Winsock (stack-ul de comunicatie Windows, unde ai nevoie de un pointer la o structura WSADATA, trimisa prin referinta, ce va contine ulterior informatii despre Winsock si de versiunea Winsock, 2.2 probabil).

WSAStartup(MAKEWORD(2,2), &wsaData)

Iar la final va trebui sa apelezi WSACleanup();.

Imi e lene sa explic mai multe, uite ce am scris eu mai demult:


/*
Nume: FileDownloader v0.1
Autor: Ionut Popescu
Data: 12-13 Noiembrie 2011
Descriere: Descarca un fisier de la URL-ul specificat in locatia specificata
*/

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winsock2.h>

#define WIN32_LEAN_AND_MEAN

/* Prototipurile functiilor */

void InitWinsock();
char *GetServer(const char *url);
char *GetIP(const char *server);
char *BuildHTTPRequest(const char *url);
int DownloadFile(const char *url, const char *filename);

/* Functia descarca un fisier de la adresa specificata */

int DownloadFile(const char *url, const char *filename)
{
char *request = NULL, *server = NULL, *server_ip = NULL, recv_buffer[4096];
SOCKET sock;
struct sockaddr_in conn;
int eroare_connect = -1, rez_send = -1, rez_recv = -1, bytes = 0, first_packet = 1;

/* Cream request-ul, si memoram IP-ul serverului */

request = BuildHTTPRequest(url);
server = GetServer(url);
server_ip = GetIP(server);

sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

/* Verificam crearea socketului */

if(sock == INVALID_SOCKET)
{
puts("Eroare, nu s-a putut crea socketul");
if(WSAGetLastError() == WSAENETDOWN) puts("- Problema cu conexiunea la internet");

exit(EXIT_FAILURE);
}

/* Facem "setarile" necesare si ne conectam la server */

conn.sin_family = AF_INET;
conn.sin_port = htons(80);
conn.sin_addr.s_addr = inet_addr(server_ip);

eroare_connect = connect(sock, (struct sockaddr *)&conn, sizeof(conn));

/* Verificam daca s-a realizat conexiunea */

if(eroare_connect == SOCKET_ERROR)
{
puts("Eroare la conectarea la server");
eroare_connect = WSAGetLastError();

switch(eroare_connect)
{
case WSAENETDOWN:
puts("- Problema cu conexiunea la internet");
break;
case WSAEADDRNOTAVAIL:
puts("- Adresa nu este valida");
break;
case WSAECONNREFUSED:
puts("- Conexiunea a fost refuzata");
break;
case WSAENETUNREACH:
puts("- Nu s-a putut realiza conexiunea la retea");
break;
case WSAEHOSTUNREACH:
puts("- Nu s-a putut realiza conexiunea la server");
break;
case WSAETIMEDOUT:
puts("- Conexiunea a esuat dupa timpul limita");
break;
default:
printf("- A intervenit eroarea cu codul: %d\n", eroare_connect);
}

closesocket(sock);
exit(EXIT_FAILURE);
}

/* Trimitem request-ul */

rez_send = send(sock, request, strlen(request), 0);

if(rez_send == SOCKET_ERROR)
{
puts("Eroare la trimiterea request-ului");

rez_send = WSAGetLastError();

switch(rez_send)
{
case WSAENETDOWN:
puts("- Problema cu conexiunea la internet");
break;
case WSAECONNABORTED:
puts("- Conexiunea a fost terminata dupa timpul limita");
break;
case WSAECONNRESET:
puts("- Conexiunea a fost resetata de server");
break;
case WSAETIMEDOUT:
puts("- Conexiune inchisa din cauza retelei sau serverului respectiv");
break;
default:
printf("- A intervenit eroarea cu codul: %d\n", rez_send);
}
}

/* Nu mai trimitem date */

shutdown(sock, SD_SEND);

/* Citim raspunsul de la server */

do
{
bytes = recv(sock, recv_buffer, 4096, 0);

if(bytes > 0)
{
/* Daca e primul pachet, separam datele de headerele HTTP */

if(first_packet == 1)
{
char *header = recv_buffer;
char delim[5] = {0};
int pos_buf = 0;

/* Prevenim eventuale probleme */

//if(strlen(recv_buffer) < 4) continue;

sprintf(delim, "\r\n\r\n");

//while(recv_buffer[pos_buf+4] && (strncmp(&recv_buffer[pos_buf], delim, 4) != 0)) pos_buf++;

printf("%s", &recv_buffer[0]);

//break;

first_packet = 0;
}
else puts(recv_buffer);

break;
}
else if(bytes == 0)
{
puts(recv_buffer);
}
else
{
puts("Eroare la citirea datelor de la server");

rez_recv = WSAGetLastError();

switch(rez_recv)
{
case WSAENETDOWN:
puts("- Problema cu conexiunea la internet");
break;
case WSAECONNABORTED:
puts("- Conexiunea a fost terminata dupa timpul limita");
break;
case WSAECONNRESET:
puts("- Conexiunea a fost resetata de server");
break;
case WSAETIMEDOUT:
puts("- Conexiune inchisa din cauza retelei sau serverului respectiv");
break;
default:
printf("- A intervenit eroarea cu codul: %d\n", eroare_connect);
}
}

} while(bytes > 0);

closesocket(sock);

return 1;
}

/* Functia returneaza IP-ul unui server */

char* GetIP(const char *server)
{
struct hostent *host;
struct in_addr address;

host = gethostbyname(server);

/* Verificam rezultatul */

if(host == NULL)
{
int eroare_ip = -1;

puts("A intervenit o eroare la preluarea IP-ului serverului");

switch(eroare_ip = WSAGetLastError())
{
case WSAHOST_NOT_FOUND:
puts("- Serverul nu a fost gasit");
break;
case WSANO_DATA:
puts("- Nu a fost gasit niciun IP pentru server");
break;
default:
printf("- A intervenit eroarea cu codul: %d\n", eroare_ip);
}

exit(EXIT_FAILURE);
}

/* Verificare si conversie */

if(host->h_addr_list[0] == 0)
{
puts("Eroare, nu s-a gasit niciun IP pentru server");
exit(EXIT_FAILURE);
}

/* Convertim reprezentarea*/

address.s_addr = *(u_long*)host->h_addr_list[0];
/* address = *(struct in_addr*)(host->h_addr_list[0]); */

/* Convertim adresa la sir de caractere si o returnam */

return inet_ntoa(address);
}

/* Functia construieste headerele HTTP necesare, memoram serverul in al doilea parametru */

char *BuildHTTPRequest(const char *url)
{
const char browser[] = "Mozilla/5.0 (Windows NT 6.1; rv:7.0.1) Gecko/20100101 Firefox/7.0.1";
char *request = NULL, *local_url = NULL, *host = NULL;
char fileurl[1024];

/* Prevenim buffer oveflow */

if(strlen(url) > 1024) return NULL;

host = GetServer(url);
local_url = (char *)malloc(1024);

/* Extragem si numele fisierului */

if(strncmp(url, "http://", 7) == 0) strcpy(local_url, url +7);
else strcpy(local_url, url);

strcpy(fileurl, local_url + strlen(host));

/* Alocam spatiu si cream headerul */

request = (char *)malloc(4096);
sprintf(request, "GET %s HTTP/1.1\r\nHost: %s\r\nUser-Agent: %s\r\n\r\n", fileurl, host, browser);

return request;
}

/* Functia returneaza serverul dintr-un URL */

char *GetServer(const char *url)
{
char *local_url = NULL, *host = NULL;
int i = 0;

/* Prevenim buffer oveflow */

if(strlen(url) >= 1024) return NULL;

/* Extragem datele necesare pentru a crea headerul */

local_url = (char *)malloc(1024);

if(strncmp(url, "http://", 7) == 0) strcpy(local_url, url +7);
else strcpy(local_url, url);

/* Copiem serverul in variabila host */

host = (char *)malloc(1024);

while(local_url[i] && local_url[i] != '/')
{
host[i] = local_url[i];
i++;
}
host[i] = '\0';

return host;
}

/* Alocam resursele Winsock si verificam pentru potentiale erori */

void InitWinsock()
{
WSADATA wsaData;

/* Initializare Winsock */

if(WSAStartup(MAKEWORD(2,2), &wsaData))
{
int eroare_wsa = -1;
puts("A intervenit o eroare la initializarea Winsock:");

switch(eroare_wsa = WSAGetLastError())
{
case WSASYSNOTREADY:
puts("- Problema cu conexiunea la Internet");
break;
case WSAEPROCLIM :
puts("- Problema cu resursele alocate de sistemul de operare");
break;
default:
printf("- A intervenit eroarea cu codul: %d\n\n", eroare_wsa);
}

exit(EXIT_FAILURE);
}
}

/* Main-ul clasic */

int main()
{
InitWinsock();

DownloadFile("http://www.un.org/Depts/Cartographic/map/profile/romania.pdf", NULL);

WSACleanup();

return 0;
}

E destul de explicat, ar trebui sa se inteleaga.

Apoi, am mai scris prima parte pentru un astfel de articol:

http://www.codexpert.ro/articole.php?id=33

Si azi am facut un client UDPv6, pe un anumit IPv6, daca ai nevoie de ceva informatii, intreaba-ma.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...