Programowanie sieciowe na Linuksie

Bash, C, C++, Java, PHP, Ruby, GTK, Qt i wiele innych - wszystko tutaj.
KORraN
Piegowaty Guziec
Piegowaty Guziec
Posty: 17
Rejestracja: 12 mar 2007, 15:49
Płeć: Mężczyzna
Wersja Ubuntu: 8.04
Środowisko graficzne: GNOME
Kontakt:

Programowanie sieciowe na Linuksie

Post 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 :)
Awatar użytkownika
doles2
Sędziwy Jeż
Sędziwy Jeż
Posty: 46
Rejestracja: 24 lip 2006, 19:58
Płeć: Mężczyzna
Wersja Ubuntu: 11.10
Środowisko graficzne: KDE Plasma
Architektura: x86_64

Odp: Programowanie sieciowe na Linuksie

Post 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.
Awatar użytkownika
el.pescado
Zakręcona Traszka
Zakręcona Traszka
Posty: 734
Rejestracja: 26 maja 2005, 11:43
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: GNOME
Architektura: x86
Kontakt:

Odp: Programowanie sieciowe na Linuksie

Post 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.
KORraN
Piegowaty Guziec
Piegowaty Guziec
Posty: 17
Rejestracja: 12 mar 2007, 15:49
Płeć: Mężczyzna
Wersja Ubuntu: 8.04
Środowisko graficzne: GNOME
Kontakt:

Odp: Programowanie sieciowe na Linuksie

Post 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?
siesiek
Piegowaty Guziec
Piegowaty Guziec
Posty: 6
Rejestracja: 16 mar 2008, 13:50
Płeć: Mężczyzna
Wersja Ubuntu: 8.04
Środowisko graficzne: GNOME

Odp: Programowanie sieciowe na Linuksie

Post 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ć :)
KORraN
Piegowaty Guziec
Piegowaty Guziec
Posty: 17
Rejestracja: 12 mar 2007, 15:49
Płeć: Mężczyzna
Wersja Ubuntu: 8.04
Środowisko graficzne: GNOME
Kontakt:

Odp: Programowanie sieciowe na Linuksie

Post 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.
siesiek
Piegowaty Guziec
Piegowaty Guziec
Posty: 6
Rejestracja: 16 mar 2008, 13:50
Płeć: Mężczyzna
Wersja Ubuntu: 8.04
Środowisko graficzne: GNOME

Odp: Programowanie sieciowe na Linuksie

Post autor: siesiek »

Spoko :) zawsze do usług :) poza tym każdemu się zdarza jakiś głupi błąd :) normalka w programowaniu :razz:
Awatar użytkownika
el.pescado
Zakręcona Traszka
Zakręcona Traszka
Posty: 734
Rejestracja: 26 maja 2005, 11:43
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: GNOME
Architektura: x86
Kontakt:

Odp: Programowanie sieciowe na Linuksie

Post 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.
mardhuk
Piegowaty Guziec
Piegowaty Guziec
Posty: 14
Rejestracja: 03 lis 2007, 13:54
Płeć: Mężczyzna
Wersja Ubuntu: 9.04
Środowisko graficzne: GNOME
Architektura: x86

Odp: Programowanie sieciowe na Linuksie

Post 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źć)
Awatar użytkownika
Kastagir
Sędziwy Jeż
Sędziwy Jeż
Posty: 89
Rejestracja: 09 sty 2006, 16:36
Płeć: Mężczyzna
Wersja Ubuntu: 17.04
Środowisko graficzne: Inne
Architektura: x86_64

Odp: Programowanie sieciowe na Linuksie

Post 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.
"Search you should use, my young padawan"
kacperek29
Piegowaty Guziec
Piegowaty Guziec
Posty: 20
Rejestracja: 17 gru 2007, 17:31
Płeć: Mężczyzna
Wersja Ubuntu: 11.04
Środowisko graficzne: GNOME
Architektura: x86_64

Odp: Programowanie sieciowe na Linuksie

Post 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?
ODPOWIEDZ

Wróć do „Programowanie”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 3 gości