Skip to content

CTcpFwd – klasa przekierowań stdin/stdout na gniazda sieciowe

Witam,

Kilka tygodni temu miałem przyjemność brać udział w 24-godzinnym, drużynowym maratonie programistycznym (pozdrowienia dla Pawła i Wojtka!). W związku z naturą konkursu, zostałem zobowiązany do stworzenia prostej klasy, pozwalającej na przekierowywanie gniazd sieciowych na standardowe wejście/wyjście (stdin / stdout), co w znacznym stopniu ułatwić miało komunikację z serwerem konkursowym. Ponieważ (przynajmniej w zamyśle), praca miała się odbywać zarówno na platformie Microsoft Windows jak i GNU/Linux, klasa ta musiała być również maksymalnie przenośna. W ten sposób powstał prezentowany dziś kawałek kodu o nazwie CTcpFwd.

Po zakończeniu konkursu zdecydowałem się ujednolicić kod oraz wprowadzić pewne drobne poprawki – w chwili obecnej powinien być już w pełni używalnym modułem. Należy jednak pamiętać, że kod ten ma charakter projektu Proof of Concept – jego głównym zadaniem jest prezentacja sposobu przekierowania socketów na stdin/out w systemie Windows które, jak się okazuje, nie jest wcale trywialne.

Ta niewielka klasa umożliwia programiście tworzenie oraz zamykanie wielu nazwanych, zdalnych połączeń (metody Connect, Disconnect), oraz przełączanie standardowego wejścia i wyjścia pomiędzy gniazdami, przy użyciu wcześniej zdefiniowanych nazw. Klasa wyłącza domyślnie zarówno użycie algorytmu buforowania Nagle’a (flaga TCP_NODELAY), jak i buforowanie stdin/out. Przykładowe użycie przedstawione jest poniżej:

CTcpFwd Sock("Google","google.com",80);

puts("Sending a request...");

Sock.SwitchStdout("Google");
printf("GET http://www.google.com/ HTTP/1.1\n"
       "Host: http://www.google.com/\n\n");

Sock.SwitchStdout("DefaultStdout");
Sock.SwitchStdin("Google");
while(fgets(buffer,sizeof(buffer),stdin))
  printf("%s",buffer);

Powyższy kod łączy się z hostem google.com na porcie HTTP, wysyła proste żądanie a następnie wypisuje na standardowe wyjście odpowiedź serwera – wszytko to odbywa się za pośrednictwem standardowego wejścia/wyjścia.

Pełną paczkę, zawierającą kod źródłowy klasy (napisanej w C++) można pobrać tutaj (6 kB)

W miarę możliwości, postaram się umieścić na blogu szersze wyjaśnienie mechanizmów wykorzystanych w kodzie, w najbliższym czasie. W razie jakichkolwiek problemów z kompilacją lub działaniem proszę o bezpośredni kontakt ;>

Komentarze jak zwykle mile widziane ;>

{ 3 } Comments

  1. Scout | 22-kwi-10 at 02:26:10 | Permalink

    Good work j00ru!

  2. Gynvael Coldwind | 23-kwi-10 at 02:52:20 | Permalink

    Using plain old printf/scanf for network communication… thats just awesome ;)
    Great work ;)

  3. przemoc | 28-kwi-10 at 12:03:29 | Permalink

    Simple idea + implementation = success. Well done, j00ru!

    It may sound like a cliche, but ideas w/o PoC are not so worthful, even if they are simple. This simplicity is important (but it doesn’t mean that code also will be simple), because overcomplicated ideas often lead to horrible half-baked code scraps or even abandoning implementation stage. Saving the world always can (and should) be postponed. For developer’s own good. :)

    +1 for portability, -1 for coding convention.
    Methods and its’ arguments names starting with upper case? Space indents? Awful. ;)

Post a Comment

Your email is never published nor shared. Required fields are marked *