Strona 1 z 1

Programowanie sieciowe na Linuksie

: 06 cze 2008, 22:50
autor: KORraN
Mam podstawy programowania w C++ i teraz chciałem spróbować napisać coś sieciowego (np. pobranie strony WWW na dysk itp.). Szukam materiałów na ten temat. Znalazłem co nieco na 4programmers.net i http://programowanie-linux.wikidot.com/sockety

Wszystkie materiały są jednak dosyć ciężko napisane i nie mogę się połapać, a w dodatku przykładowe programy też nie zawsze działają. Posiada ktoś jakieś dobre materiały napisane w miarę przystępnym językiem? Może być po angielsku :). Będę bardzo wdzięczny :)

Odp: Programowanie sieciowe na Linuksie

: 06 cze 2008, 23:17
autor: doles2
Zupełna podstawa: http://www.pradnik.net/netman/
Twoje linki traktuj jako uzupełnienie. Ja osobiście oprócz tego u góry szukałem po google różnych rzeczy i głównie trafiałem na ciekawe materiały publikowane przez wykładowców dla swoich studentów (na szczęście dostępne dla każdego).
To się również przyda ( w końcu całe programowanie sieciowe jest oparte na koncepcji gniazd BSD): http://www.cs.put.poznan.pl/mszychowiak ... etAPI.html
Tak propo tego pierwszego linka co podałem, bardzo dobry tutorial od 0 do no powiedzmy standardowego poziomu. Jednak co mnie bardzo w nim irytuje to język. Nie wiem czego autor chciał dokonać pisząc ten kurs tak prostackim i błazeńskim językiem. Idioci są zbyt głupi na programownie gniazd sieciowych zaś ludzi o zdrowym rozsądku ten język tylko drażni, no ale to moje odczucie.

Odp: Programowanie sieciowe na Linuksie

: 07 cze 2008, 17:50
autor: el.pescado
Można skorzystać też z wysokopoziomowych bibliotek, jak np. GNet czy snl - ogólnego użytku, albo bibliotek o specyficznym zastosowaniu, np. libcurl - do przesyłania plików przez HTTP, WWW i tym podobnymi.

Odp: Programowanie sieciowe na Linuksie

: 14 cze 2008, 18:28
autor: KORraN
doles2 -> Dzięki, chyba jest przyjaźniej ten tekst napisany. Choć fakt, gość na siłę próbował zachować luźny format oryginału :P.

el.pescado -> Właśnie chodzi mi o pisanie na socketach, bez używania niestandardowych bibliotek :)

EDIT:
Udało mi się przebrnąć przez artykuły o tworzeniu aplikacji sieciowych. Najbardziej pomocny okazał się ten tutorial. Spróbowałem napisać coś, co pozwoli mi przetestować sockety - program pobierający stronę www. Oto kod:

Kod: Zaznacz cały

#include <cstdio>
#include <cstdlib>
#include <string>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>

int main(void) {
	int s, result;
	struct sockaddr_in taddr;
	char zapytanie[] = "GET / HTTP/1.1\nHost: www.google.pl\n\n";
	char odp[2048];
	
	/* Tworzenie gniazda */
	s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (s < 0) {
		perror("socket");
		return 1;
	}
	
	/* Zerowanie struktury adresowej */
	memset(&taddr, 0, sizeof(struct sockaddr));
	
	/* Wypelnianie struktury adresem docelowym */
	taddr.sin_family = AF_INET;
	taddr.sin_port = htons(80);
	taddr.sin_addr.s_addr = inet_addr("72.14.207.99");
	
	/* Laczenie z serwerem */
	result = connect(s, (struct sockaddr*)&taddr, sizeof(struct sockaddr));
	if (result < 0) {
		close(s);
		perror("connect");
		return 1;
	}
	
	/* Wymiana danych */
	send(s, zapytanie, strlen(zapytanie), 0);
	recv(s, odp, 2048, 0);
	printf("Odpowiedz serwera: %s", odp);
	
	/* Zamkniecie gniazda */
	close(s);
	return 0;
}
Problem polega na tym, że program nie chce pobrać całego kodu. Gdy zwiększa pojemność chara odp to przy wyświetlaniu od pewnego momentu pojawiają się krzaczki...

I druga rzecz - dlaczego gdy próbuję dołączyć iostream i użyć cout, kompilator wyrzuca brak deklaracji elementu cout?

Odp: Programowanie sieciowe na Linuksie

: 14 cze 2008, 20:14
autor: siesiek
Za sockety jeszcze się nie brałem, ale żeby użyć strumienia cout to oprócz dołączenia biblioteki iostream musisz albo globalnie użyć przestrzeni nazw std (using namespace std) albo przy każdym wywołaniu cout'a dopisać zasięg nazwy std (std::cout). Wtedy kompilator przestanie się rzucać :)

Odp: Programowanie sieciowe na Linuksie

: 14 cze 2008, 20:44
autor: KORraN
siesiek -> Ale błęda strzeliłem... Dzięki za zwrócenie uwagi :)

Pozostaje jeszcze problem z odebraniem całej strony, a nie tylko części.

Odp: Programowanie sieciowe na Linuksie

: 14 cze 2008, 21:26
autor: siesiek
Spoko :) zawsze do usług :) poza tym każdemu się zdarza jakiś głupi błąd :) normalka w programowaniu :razz:

Odp: Programowanie sieciowe na Linuksie

: 15 cze 2008, 17:25
autor: el.pescado

Kod: Zaznacz cały

recv(s, odp, 2048, 0);
Powyższy kod oznacza tyle:
- przeczytaj dane z gniazdka s, umieść je w tablicy odp, której wielkość wynosi2048, i zwróć ilość przeczytanych bajtów.
Biorąc pod uwagę powyższe, jasnym jest że program nie pobierze strony, która jest większa niż 2048 bajtów - bo tyle się tylko może zmieścić w buforze przekazanym do funkcji recv.
Jeśli się przekaże większy bufor, nie zostanie on wypełniony w całości - dlatego w końcowej jego części będą znajdować się śmiecie.

(dygresja: tekst w C jest zapisywany jako tablica bajtów, kończąca się znakiem '\0' (czyli po prostu bajtem o wartości 0). Funkcja recv nie dodaje bajtu zerowego na koniec bufora (bo funkcja recv ma operować na dowolnych tablicach, nie tylko tekstowych). Dlatego więc, po przekazaniu takiej tablicy do funkcji printf z formatem %s, który oczekuje bajtu zerowego na końcu łańcucha znaków śmiecie lądują na ekranie. Koniec dygresji)

Wracając do tematu, po pierwsze należy przeczytać stronę podręcznika systemowego o funkcji recv:

Kod: Zaznacz cały

man 2 recv
, ewentualnie o funkcji read:

Kod: Zaznacz cały

man 2 read
(funkcja recv z ostatnim parametrem równym zero jest równoważna funkcji read). Potem, dane trzeba czytać w pętli, aż recv/read nie zwróci 0, oznaczającego koniec pliku/strumienia:

Kod: Zaznacz cały

char buffer[BUFFER_SIZE];
size_t bytes_read = read (s, buffer, BUFFER_SIZE);
while (bytes_read > 0) {
    fprintf (buffer, 1, bytes_read, stdout); /* Wypisanie danych na ekran */
    bytes_read = read (s, buffer, BUFFER_SIZE); /* Pobranie nowych danych */
}
EDIT:
kompilator wyrzuca brak deklaracji elementu cout?
cout znajduje się w przestrzeni nazw std, więc trzeba albo odwoływać się do std::cout, albo gdzieś na górze programu dopisać "using namespace std;", wtedy wszystki symbole z przestrzeni std będą dostępne w głównej przestrzni nazw.

Odp: Programowanie sieciowe na Linuksie

: 08 lip 2009, 12:39
autor: mardhuk
Ja chciałbym dla odmiany zapytać o jakąś dobrą książkę o socketach (oczywiście w kontekście linuxa), dostępną w języku polskim najlepiej (wyłączając ksiązkę Warrena, której nigdzie nie mogłem znaleźć)

Odp: Programowanie sieciowe na Linuksie

: 08 lip 2009, 17:00
autor: Kastagir
mardhuk pisze:Ja chciałbym dla odmiany zapytać o jakąś dobrą książkę o socketach (oczywiście w kontekście linuxa), dostępną w języku polskim najlepiej (wyłączając ksiązkę Warrena, której nigdzie nie mogłem znaleźć)
Richard Stevens, Programowanie usług sieciowych to jedyne co mi przychodzi do głowy.

Odp: Programowanie sieciowe na Linuksie

: 08 lip 2009, 19:27
autor: kacperek29
Jest jeszcze Marc J. Rochkind Programowanie w systemie UNIX dla zaawansowanych.
Nie znam osobiście tej pozycji.

Sam się zastanawiam i chętnie poznał bym Waszą opinie co wybrać Rochkinda czy Stevensa?