#programowanie #sieci #siecikomputerowe #jezykc #winsock #socket Hej Mireczki, czy Ktoś z Was ogarnia bibliotekę socket?
Chodzi mi tutaj o podstawową funkcję connect(), czy można ją wykorzystać do tego aby połączyć się z adresem 8.8.8.8 potwierdzając tym samym że mamy dostępne połącznie interenetowe? Gdzieś przeczytałem że to wystarczy - taki prosty PING. Jednak kiedy oglądałem źródła komendy ping.c to tam nie korzystali z connect() tylko od razu po stwqorzeniu socketa dawali send() wysylajac pakiet icmp. Jak zrobić? Chodzi mi tu o szybkie sprawdzenie polaczenia z internetem. czy connect() powinien zadziałać i lepiej coś wysłać send() ?
Chodzi mi tutaj o podstawową funkcję connect(), czy można ją wykorzystać do tego aby połączyć się z adresem 8.8.8.8 potwierdzając tym samym że mamy dostępne połącznie interenetowe? Gdzieś przeczytałem że to wystarczy - taki prosty PING. Jednak kiedy oglądałem źródła komendy ping.c to tam nie korzystali z connect() tylko od razu po stwqorzeniu socketa dawali send() wysylajac pakiet icmp. Jak zrobić? Chodzi mi tu o szybkie sprawdzenie polaczenia z internetem. czy connect() powinien zadziałać i lepiej coś wysłać send() ?
MamCieNaHita
2023-04-24 12:58:11
+2
@PlugaweWarzywo: zastanów się na której warstwie chcesz działać. ping działa po ICMP, a connecta zwykle używasz do zestawienia TCP
gentooman
2023-04-24 15:37:20
+1
@PlugaweWarzywo: Jeszcze możesz mieć problem uprawnień. Żeby wysłać pakiet ICMP potrzebujesz socket typu RAW, a tego zwykły użytkownik nie może zrobić. Systemowy Ping ma dodatkowy atrybut
Wcześniej ci pisałem że takie sprawdzenie lepiej robić po HTTP
CAP_NET_RAW na Linuxach. Na Windowsa jest specjalne API https://learn.microsoft.com/en-us/windows/win32/api/icmpapi/nf-icmpapi-icmpsendecho?redirectedfrom=MSDNWcześniej ci pisałem że takie sprawdzenie lepiej robić po HTTP
gentooman
2023-04-25 21:14:31
+1
@PlugaweWarzywo: SIOCGIFCONF to ci powie jaki masz adres IP na karcie sieciowej. Jest to za mało żeby stwierdzić czy masz połączenie z internetem. To nawet nie mówi ci czy masz poprawną komunikację z najbliższym routerem, bo przecież te adresy można ustawiać ręcznie i w cale nie muszą być poprawne.
Jedyny sposób na sprawdzenie czy faktycznie masz połączenie z internetem to wysłanie zapytania w ten internet i oczekiwanie że otrzymasz odpowiedź. Zastanów się czym w ogóle jest to "połączenie z internetem". Masz po drodze X routerów i jedyna możliwość żeby stwierdzić czy połączenie działa to otrzymanie odpowiedzi na wysłane żądanie.
Jedyny sposób na sprawdzenie czy faktycznie masz połączenie z internetem to wysłanie zapytania w ten internet i oczekiwanie że otrzymasz odpowiedź. Zastanów się czym w ogóle jest to "połączenie z internetem". Masz po drodze X routerów i jedyna możliwość żeby stwierdzić czy połączenie działa to otrzymanie odpowiedzi na wysłane żądanie.
PlugaweWarzywo
[OP]
2023-04-24 15:04:26
+0
@MamCieNaHita: dzieki, posprawdzam
PlugaweWarzywo
[OP]
2023-04-24 22:35:13
+0
@MamCieNaHita: @gentooman Udało mi się to ogarnąć za pomocą TCP i connect - tylko że tym razem zamiast adresu 8.8.8.8 czyli dns uzyłem jednego z adresów strony googlw.com (216.58.213.0).. tylk otak sie jeszcz zastanawiam, czy nie lepiej by użyć komendy gethostbyname() z paramaterem "www.google.com" i jesli zwóric błąd to oznacza ze nie ma dostepu do sieci?? czy może to zapomocą connect() bedzie szybsze..
gentooman
2023-04-24 23:07:08
+0
@PlugaweWarzywo: gethostbyname prosi systemowy resolver dns żeby rozwiązał nazwę. Jeśli nazwy nie ma w cache to resolver wysyła pakiet UDP do serwera DNS. Resolver też może cachować wyniki, ale tu już nie wiem na jakich zasadach ten cache jest czyszczony, wiec możliwe ze dostaniesz fałszywie pozytywne wyniki, czyli internetu nie ma, ale nazwa jeszcze jest w cache. Dodatkowo twoim serwerem DNS może być twój router który też ma swój cache i mimo ze nie ma dostępu do internetu to będzie zwracał odpowiedzi. Sporo w tym mojego gdybania i wymyślania najgorszego możliwego scenariusza. Możliwe że do twoich zastosowań będzie wystarczające.
Najlepszy sposób to zrobienie requesta HTTP i sprawdzenie czy response jest taki jak oczekiwany
- bardzo mała szansa ze coś go zablokuje
- nie polegasz na cache o których możesz nawet nie wiedzieć
- wykrywasz Captive portale, które mogą dodatkowo przepuszczać DNS i ICMP
Najlepszy sposób to zrobienie requesta HTTP i sprawdzenie czy response jest taki jak oczekiwany
- bardzo mała szansa ze coś go zablokuje
- nie polegasz na cache o których możesz nawet nie wiedzieć
- wykrywasz Captive portale, które mogą dodatkowo przepuszczać DNS i ICMP
PlugaweWarzywo
[OP]
2023-04-25 00:11:47
+0
@gentooman: Hej, dzięki za info - tak właśnie było w przypadku "gethostbyname" - gdy odłączyłem kabel nadal dostawalem info ze jestem ONLINE - wiec to zły pomysł.. Generalnie udało mi się zrobić tak jak mówisz - tylko jest jeden problem. Chodzi o czas timeout dla oczekiwania na connect(). Jeśli odłacze kabel to czekam chyba ze 20s. Na Windowsie użyłem
Niestety w normalnej bibliotece bsd socket niema tej opcji.. i nie wiem jak to obejść -
TCP_MAXRT w setsockopt(my_socket, IPPROTO_TCP, TCP_MAXRT, (char*)&timeout, sizeof(timeout)); i działało - np. 1 sekunda timeoutu.Niestety w normalnej bibliotece bsd socket niema tej opcji.. i nie wiem jak to obejść -
SO_RCVTIMEO i SO_SNDTIMEO, nie działa
gentooman
2023-04-25 00:54:09
+0
@PlugaweWarzywo: Dawno nie pisałem na gołych socketach, ale na stacku piszą ze to się robi nieblokującym socketem + poll/select z timeoutem https://stackoverflow.com/a/61960339 albo https://stackoverflow.com/a/2597774 Oczywiście na Windowsie to nie zadziała.
PlugaweWarzywo
[OP]
2023-04-25 11:38:19
+0
@gentooman: dzięki ponownie za pomoc.. tak to postaram sie zrobić..
PlugaweWarzywo
[OP]
2023-04-25 20:43:46
+0
@gentooman: To rozwiazanie zadziałało, działa i na Windowsie i na zupełnie innej platformie, dzieki.. jeszcze ponoć jest inny sposób z użyciem ioctl() SIOCGIFCONF, zeby interfesy sprawdzac jakkie mają flagi, moze taki bylby lepszy bo nie trzeba by sie łączyć z jakimś randomowym serwerem - ale generalnie ten pierwszy mi w zupelnosci wystarcza - ten drogi sproboje zaimplementowac do porowania - jak zadziala to moze jego zostawie