piątek, 16 sierpnia 2019

Pożyteczne (techniczne) linki

Poniżej umieszczam trochę pożytecznych linków, z których czasami korzystam.

DistroWatch.com - dokładny przegląd dystrybucji Linuksa i BSD:
https://distrowatch.com/

Cheat.sh - ściągawka do komend Unix/Linux i języków programowania:

Explain Linux Commands - wpisujemy pełną komendę np. ps -aux i dostajemy pełne wyjaśnienie, co robi komenda oraz jej parametry:

What is my IP - mój publiczny i prywatny adres IP:
https://www.cleancss.com/what-is-my-ip/

Default Router Settings - domyślne nazwy i hasła użytkowników oraz adresy IP routerów, modemów, kamer IP i innych urządzeń sieciowych:
https://www.cleancss.com/router-default/

BezKompilatora.pl - ciekawy blog o Linuksie:
https://www.bezkompilatora.pl/

Crontab Guru - edytor (kreator) tabeli crontab dla harmonogramu zadań cron:
https://crontab.guru/

repl.it - kompilatory online dla różnych języków programowania:
https://repl.it/

Circuit Simulator - symulator układów elektronicznych w przeglądarce:
http://lushprojects.com/circuitjs/

Crypto-IT : Protokoły TCP/IP - opis TCP/IP:
http://www.crypto-it.net/pl/teoria/protokoly-tcp-ip.html

Codecademy - kursy online z języków programowania:
https://www.codecademy.com/

Rosetta Code - różne zadania programistyczne w bardzo wielu językach programowania:
http://www.rosettacode.org/wiki/Category:Programming_Tasks
np. najprostszy program Hello World napisany w ponad 400 różnych językach programowania:
http://www.rosettacode.org/wiki/Hello_world/Text

SS64 - opis komend wiersza poleceń dla systemów Linux, macOS i Windows oraz opis poleceń i funkcji dla SQL, VBS i PowerShell:
https://ss64.com/

VirusTotal - można sobie online przeskanować plik za pomocą różnych silników antywirusowych:
https://www.virustotal.com

WolframAlpha - strona ta formułuje odpowiedź na pytanie zadane w języku naturalnym, wykonuje obliczenia, przedstawia dane statystyczne, rozwiązuje równania itp.:
https://www.wolframalpha.com/

ark.intel.com - specyfikacje produktów Intela:
https://ark.intel.com

FORBOT - elektronika, Arduino, Raspberry Pi, kursy:
https://forbot.pl/blog/

BlogIT by Artur Dębski - pożyteczne notatki z różnych dziedzin IT:
http://blogit.one.pl/news_cats.php

Kalkulator IP - na podstawie adresu IP i maski oblicza adres sieci, adres rozgłoszeniowy oraz ilość hostów w sieci:
https://42.pl/ipcalc/

--- Na koniec moje dwa ulubione na dzień dzisiejszy systemy operacyjne ---

FreeBSD:
https://www.freebsd.org/
https://www.freshports.org/
https://pl.wikipedia.org/wiki/FreeBSD

Linux Mint:
https://www.linuxmint.com/
https://pl.wikipedia.org/wiki/Linux_Mint

czwartek, 18 lipca 2019

FreeBSD 12.0 - instalacja systemu

FreeBSD jest darmowym systemem operacyjnym z rodziny Unix (nie jest to kolejna dystrybucja Linuksa!) dostępnym z pełnym kodem źródłowym. System jest zgodny z normą POSIX i jest dostępny na wiele architektur sprzętowych (nawet na takie urządzenia jak Raspberry Pi). FreeBSD korzysta z opartego na źródłach systemu pakietowania znanego jako porty oraz prekompilowanych pakietów binarnych z domyślnymi opcjami dla wszystkich aktualnie obsługiwanych wersji i architektur sprzętowych FreeBSD.

Wersję instalacyjną systemu na różne architektury sprzętowe można ściągnąć z oficjalnej strony https://www.freebsd.org/

No to zaczynamy instalację:



Na początku wybieramy układ klawiatury:



Podajemy nazwę hosta w sieci:



Wybieramy opcjonalne komponenty. Warto zaznaczyć ports, żeby móc później instalować programy z pakietów zawierających kody źródłowe, tzw. portów:



Następnie tworzymy partycję na dysku przeznaczoną na system FreeBSD. Mamy do wyboru dwa systemy plików - UFS (Unix File System) oraz ZFS, który jest szybszy, ale trudniejszy w konfiguracji. Ja wybrałem UFS (w rzeczywistości jest to nowszy UFS2):



Następnie mamy wybór, czy utworzyć partycję zajmującą cały dysk twardy (Entire Disk), czy tylko część dysku (Partition - gdy chcemy później zainstalować inny dodatkowy system np. Linux):



Kolejnym krokiem, jest wybranie schematu partycjonowania np. MBR lub GPT:



Wyskoczy podsumowanie o utworzonych partycjach i systemach plików. Wybieramy Finish:



Rozpocznie się proces instalacji plików całej dystrybucji FreeBSD:




Po zainstalowaniu wszystkich plików, należy ustalić hasło root-a:



Przystępujemy do konfiguracji karty sieciowej:







Wybieramy strefę czasową:







Wybieramy usługi (demony), które będą działać w naszym systemie:



Wybieramy dodatkowe opcje związane z bezpieczeństwem systemu:



Zakładamy dodatkowych użytkowników. Nie jest to konieczne, ale wskazane ze względów bezpieczeństwa systemu (lepiej pracować na koncie zwykłego użytkownika). W konsoli, w standardowych menedżerach okien i w niektórych środowiskach graficznych możemy logować się użytkownikiem root, ale np. połączenie środowiska graficznego KDE Plasma z menedżerem logowania SDDM nie pozwala na logowanie się do systemu użytkownikiem root:




Koniec instalacji. Warto jeszcze doinstalować podręcznik FreeBSD w naszym języku:




Możemy opuścić instalator i uruchomić ponownie komputer:





Przy pierwszym uruchomieniu systemu FreeBSD warto zaktualizować listę pakietów:

# pkg update


oraz zaktualizować wszystkie zainstalowane pakiety:

# pkg upgrade


Oprogramowanie instalujemy za pomocą polecenia pkg install, np. Midnight Commander instalujemy tak:

# pkg install mc


Programy możemy też instalować za pomocą portów, ale to zagadnienie i ogólny opis systemu (w tym plików konfiguracyjnych) to już temat na odrębny artykuł.

Warto też doinstalować X Window System (X.org - serwer X-ów) oraz środowisko graficzne np. Xfce, GNOME, KDE Plasma, Lumina itd. Jednak jest to też temat na osobny artykuł.

Przydatne linki:
- oficjalna strona FreeBSD - https://www.freebsd.org/
- oficjalne forum FreeBSD - https://forums.freebsd.org/
- wszystko o pakietach i portach - https://www.freshports.org/

wtorek, 12 lutego 2019

Docker

Docker jest narzędziem, które pozwala umieścić program oraz jego zależności w lekkim, przenośnym wirtualnym kontenerze, który można uruchomić na prawie każdym hoście z systemem Linux.

Docker zastępuje tradycyjną wirtualizację przez stosowanie czegoś co nazywa się konteneryzacją. Każdy kontener posiada wydzielony obszar pamięci, odrębny interfejs sieciowy z własnym adresem IP oraz wydzielony obszar na dysku, na którym znajduje się zainstalowany obraz systemu operacyjnego i wszystkich zależności (bibliotek) potrzebnych do działania aplikacji (uruchamiane są tylko procesy niezbędne do działania aplikacji).

Porównanie kontenerów i standardowej wirtualizacji:



Źródło: https://www.docker.com/resources/what-container

Najważniejsze pojęcia:

Demon - główny silnik Dockera (proces dockerd) - odpala nasze kontenery z aplikacjami.

Klient - aplikacja CLI o nazwie docker, komunikuje się z demonem.

Obraz - jest szablonem dla kontenera. Obrazy znajdują się w rejestrze np. https://hub.docker.com/ albo w lokalnym cache. Są tylko do odczytu.

Rejestr - miejsce do przechowywania obrazów. Oficjalny rejestr dockera to: https://hub.docker.com/

Kontener - to uruchomiona instancja danego obrazu, jest warstwą zapisywalną.

Docker jest wielowarstwowy: Kernel > Obraz > Kontener

Instalacja Dockera

Docker do pracy wymaga linuksowego kernela, więc można go uruchomić na większości dystrybucji systemu Linux. Działa też pod Windows 10 Pro i Enterprise 64-bit, wykorzystując wirtualizację Hyper-V. Można też odpalić maszynę wirtualną z Dockerem pod macOS.

Przykład instalacji dla Ubuntu 18.04 64-bit:

sudo apt install docker.io

Aby można było uruchamiać kontenery, trzeba dodać użytkownika do grupy docker:

sudo usermod -aG docker $USER

Sprawdzenie, czy Docker działa

Trzeba ściągnąć obraz hello-world z oficjalnego repozytorium:

docker run hello-world

Jak wyskoczy tekst Hello from Docker!, tzn. że kontener z obrazem hello-world uruchomił się prawidłowo.

Przykłady działania

Uruchomienie kontenera z najnowszym interpreterem języka Python:

docker run -it python

-i : uruchamia instancję kontenera w trybie interaktywnym
-t : przypisuje instancję kontenera do bieżącej konsoli (tty)

Uruchomienie kontenera z Pythonem 2.7:

docker run -it python:2.7

Kontener z Alpine Linux (lekki system Linux):

docker run -it alpine
docker run -it alpine /bin/sh
docker run alpine ls -l

Kontener z grami bsd-games (np. adventure, backgammon, battlestar, boggle, cribbage, go-fish, hunt, mille, quiz, trek, worm):

docker run -it --rm cricket/hangman hangman

--rm : usuwa kontener po zakończeniu

Aplikacja webowa:

docker run --name stsi -d -p 85:80/tcp dockersamples/static-site

--name : zdefiniowana przez użytkownika przyjazna nazwa kontenera
-d : detached mode, proces działa w tle, konsola dostępna
-p 85:80/tcp : przekierowanie portu 80/tcp kontenera na 85/tcp hosta (można odpalić w przeglądarce stronę testową http://ip_hosta:85 )
-P : przekierowanie portów kontenera na losowe wysokie porty hosta

docker port stsi
- można sprawdzić, które porty są mapowane z kontenera stsi na host

Przydatne komendy polecenia docker

docker images - lista obrazów w lokalnym cache komputera
docker info - szczegółowe informacje o Dockerze (ilość obrazów, kontenerów itp.)
docker kill - ubija działający kontener
docker port - lista mapowanych portów TCP i UDP z kontenera na host
docker ps - lista działających kontenerów
docker pull - ściąga obraz do lokalnego cache
docker push - wysyła obraz do repozytorium
docker rm - usuwa kontenery z dysku
docker rmi - usuwa obrazy z dysku
docker run - uruchamia kontener (komendę w kontenerze); jeżeli nie ma obrazu, to go ściąga (docker pull)
docker search - szuka obrazów w repozytorium
docker top - pokazuje uruchomione procesy w kontenerze
docker version - informacja o wersji Dockera
docker build - budowanie własnego obrazu kontenera

Budowanie własnego obrazu kontenera z pliku Dockerfile

W tym przykładzie zbudujemy własny kontener z obrazem Pythona 3.4 i uruchomionym programem primes_print.py, który wypisuje na ekranie liczby pierwsze.

Kod źródłowy programu w Pythonie:
https://github.com/adamblaszczyk/code-snippets/blob/master/python/primes_print.py

Tworzymy plik Dockerfile służący do budowania obrazu:

FROM python:3.4
ADD primes_print.py /
CMD python primes_print.py

Jest to przepis na budowanie obrazu:
FROM - oznacza bazowy obraz,
ADD - dodaje pliki do obrazu,
CMD - polecenie odpalane przy starcie kontenera (instancji zbudowanego obrazu).

Budujemy obraz (wykorzystując Dockerfile) na bazie obrazu python:3.4 z oficjalnego repozytorium Docker Hub:

docker build --tag=primes .

--tag : nazwa_obrazu(:wersja)

Uruchamiamy naszą instancję (kontener) nowo zbudowanego obrazu:

docker run -it --rm primes

Na tym zakończę wstęp do Dockera. Postaram się jeszcze coś o nim napisać.

wtorek, 6 czerwca 2017

Hyper-V - chwilowe wyłączenie hipernadzorcy

Hyper-V to oprogramowanie służące do wirtualizacji (hypervisor) działające na systemach serwerowych Microsoftu (od Windows Server 2008) oraz także na desktopach (od Windows 8 Pro).

Hyper-V jest uruchamiany podczas startu systemu Windows i czasami istnieje potrzeba chwilowego go wyłączenia (np. gdy mamy problemy z innym hypervisorem takim jak VirtualBox).

Funkcję Hyper-V wyłączamy narzędziem bcdedit (Boot Configuration Data) z linii poleceń cmd:

1. Uruchamiamy wiersz poleceń cmd z uprawnieniami administratora.
2. Wydajemy polecenie:

bcdedit /set hypervisorlaunchtype off

3. Restartujemy komputer.

Powrót do Hyper-V:

1. Uruchamiamy wiersz poleceń cmd z uprawnieniami administratora.
2. Wydajemy polecenie:

bcdedit /set hypervisorlaunchtype auto

3. Restartujemy komputer.

czwartek, 6 kwietnia 2017

ADB - Android Debug Bridge

Android Debug Bridge (ADB) to wszechstronne narzędzie, które pozwala kontrolować i zarządzać urządzeniem (lub emulatorem) z systemem operacyjnym Android. Za pomocą oprogramowania ADB można np. kopiować pliki z, oraz do pamięci urządzenia z Androidem, instalować oraz odinstalowywać aplikacje (pliki .apk), uzyskać dostęp do powłoki (shell) urządzenia, podejrzeć logi Androida itp. Narzędzie ADB dostępne jest dla Linux, Windows i Mac.


Instalacja ADB na komputerze

ADB jest dostępny w pakiecie SDK Platform Tools dla systemów Linux, Windows i Mac.
W systemie Linux można też go zainstalować za pomocą menadżera pakietów, np. w Linux Mint:

sudo apt-get install android-tools-adb

Można też zainstalować Android Studio - oficjalne IDE dla Androida. Program ADB znajduje się w podkatalogu platform-tools środowiska SDK. Dodatkowo w Android Studio mamy możliwość tworzenia aplikacji dla Androida w języku Java.


Włączenie debugowania na urządzeniu z Androidem

Aby program ADB w komputerze komunikował się z telefonem/tabletem z Androidem, należy włączyć Debugowanie USB:
Ustawienia > Opcje programistyczne > Debugowanie USB

Jeżeli Opcje programistyczne nie są widoczne, trzeba je uaktywnić uderzając 7 razy w Numer kompilacji:
Ustawienia > Informacje o telefonie > Numer kompilacji


Pożyteczne komendy

1) Numer wersji programu ADB

adb version

2) Wykaz wszystkich funkcji programu ADB

adb help

3) Wykaz podpiętych do komputera urządzeń z Androidem

adb devices

Jeśli lista urządzeń jest pusta, oznaczać to może, że nasze urządzenie z Androidem potrzebuje dodatkowych sterowników. Można spróbować ściągnąć sterowniki od googla: Google USB Driver - głównie dla Google Nexus. Można też próbować zainstalować oprogramowanie od producenta urządzenia, które zawiera sterownik np. dla telefonów Huawei jest to oprogramowanie HiSuite .

4) Przerwanie działania serwera ADB

adb kill-server

5) Instalacja pakietu APK (programu) na Androidzie

adb install myapp.apk

6) Deinstalacja pakietu

adb uninstall com.blogspot.wyciekpamieci.myapp

7) Kopiowanie plików z komputera do Androida

adb push C:\Users\adam\photos\photo1.jpg /sdcard/photos
- dla Windows

adb push /home/adam/photos/photo1.jpg /sdcard/photos
- dla Linux

8) Kopiowanie plików z Androida na komputer

adb pull /sdcard/photos/photo2.jpg C:\Users\adam\photos
- dla Windows

adb pull /sdcard/photos/photo2.jpg /home/adam/photos
- dla Linux

9) Logcat - logi Androida pomocne przy debugowaniu problemów

adb logcat
- zrzut logów na ekran konsoli (Ctrl-C przerywa zrzucanie logów)

adb logcat > log.txt
- zrzut logów do pliku (Ctrl-C przerywa zrzucanie logów)

10) Ponowne uruchomienie urzadzenia

adb reboot

11) Uruchomienie w Recovery

adb reboot recovery

12) Uruchomienie w Bootloaderze

adb reboot bootloader

13) Zdalna powłoka (shell) Androida

adb shell

Od teraz możemy wykonywać typowe polecenia uniksowe (ls, cd, cp, mv, rm, mkdir, pwd, touch, cat, ping, netstat, exit i wiele innych) na Androidzie. W wyniku wykonania komendy adb shell dostajemy się do pamięci urządzenia.
Znak zachęty # informuje nas o dostępie z prawami root. W przypadku pojawienia się znaku zachęty $ wpisujemy jeszcze komendę su by dostać prawa root (tylko dla zrootowanych urządzeń).
Komendy shella można wydawać bez bezpośredniego wchodzenia w powłokę, np.:

adb shell ls

adb shell cat /proc/meminfo

Pożyteczne komendy powłoki shell:

adb shell cat /proc/meminfo
- informacje na temat pamięci urządzenia z Androidem

adb shell cat /proc/cpuinfo
- informacje na temat procesora

adb shell cat /proc/version
- wersja jądra Linux na urządzeniu z Androidem

adb shell df
- sprawdzimy jakie mamy punkty montowania, jaką mają pojemność i ilość wolnej przestrzeni

adb shell getprop
- odczytamy wiele parametrów naszego systemu Android

adb shell getprop ro.build.version.release
- sprawdzimy jaką mamy wersję Androida

adb shell getprop ro.build.version.sdk
- sprawdzimy jaką mamy wersję SDK na urządzeniu

adb shell pm list packages
- lista zainstalowanych pakietów

adb shell pm path org.wikipedia
- ścieżka do pliku .apk dla danego pakietu

adb shell netcfg
- informacja o interfejsach sieciowych urządzenia

adb shell ping 8.8.8.8
- puszczenie pinga do danego hosta (tutaj do hosta o adresie 8.8.8.8) z urządzenia Android

adb shell top
- lista procesów aktualnie działających w systemie (Ctrl+C - wyjście)

wtorek, 14 lutego 2017

TCP/IP

Komunikacja w sieci oparta jest na warstwowych modelach protokołów i odniesienia. Najpopularniejsze modele warstwowe to:
- model odniesienia ISO/OSI,
- model protokołów TCP/IP.

Model ISO/OSI traktowany jest jako model odniesienia (wzorzec) dla większości rodzin protokołów komunikacyjnych. Podstawowym założeniem modelu jest podział systemów sieciowych na 7 warstw (ang. layers) współpracujących ze sobą w ściśle określony sposób.

Dla internetu sformułowano uproszczony model TCP/IP, który ma tylko 4 warstwy.



W modelu TCP/IP każda wiadomość wysłana przez aplikację przechodzi przez wszystkie warstwy TCP/IP, od najwyższej warstwy aplikacji do najniższej warstwy dostępu do sieci (każda warstwa dodaje swój własny nagłówek do danych aplikacji - zjawisko to nazywamy enkapsulacją). Następnie wiadomość jest transmitowana przez sieć do drugiego komputera. Na koniec przechodzi przez wszystkie warstwy w przeciwnym kierunku, aż do warstwy aplikacji i docelowego procesu. Usuwanie tych nagłówków po drugiej stronie komunikacji nazywamy dekapsulacją.

Na rysunku poniżej pokazano przykładową sesję TCP, która odbyła się w sieci lokalnej pomiędzy klientem 192.168.0.17 a serwerem 192.168.0.23. Klient 192.168.0.17 po połączeniu się do serwera 192.168.0.23 na porcie 6996 (za pomocą narzędzia Telnet) otrzymuje od niego komunikat "Hello". Następnie klient jako pierwszy zamyka połączenie (wychodzi z programu Telnet).
Kod źródłowy i binarny serwera:
https://github.com/adamblaszczyk/tcp-test-server




Mamy tu 7 ramek a właściwie 7 segmentów TCP. Pierwsze trzy to ustanowienie połączenia, czyli uzgadnianie trój-etapowe (three-way handshake):

1) Klient 192.168.0.17 wysyła segment SYN z losowym numerem sekwencyjnym Seq=1796127574
2) Serwer 192.168.0.23 wysyła segment SYN ACK ze swoim losowym numerem sekwencyjnym Seq=1444501807 oraz numerem potwierdzenia Ack=1796127575 (numer sekwencyjny klienta zwiększony o 1)
3) Klient wysyła segment ACK ze swoim numerem sekwencyjnym Seq=1796127575 oraz numerem potwierdzenia Ack=1444501808 (numer sekwencyjny serwera zwiększony o 1)

To kończy proces nawiązywania połączenia i pozwala na właściwą transmisję danych:
4) Wysłanie właściwych danych przez serwer - tekst "Hello" (5 bajtów) - ustawiona flaga ACK (Seq=1444501808; Ack=1796127575)
5)  Klient wysyła segment ACK potwierdzający odebranie danych (Seq=1796127575; Ack=1444501813 - numer sekwencyjny serwera zwiększony o ilość odebranych bajtów)

Zakończenie połączenia:
6) Klient wysyła segment FIN ACK kończący połączenie (Seq=1796127575; Ack=1444501813)
7) Serwer potwierdza segmentem ACK (Seq=1444501813; Ack=1796127576)
Następuje zamknięcie sesji TCP.

Nie jest to do końca wzorcowe zakończenie połączenia TCP. Może ono być zainicjowane przez dowolną stronę i powinno ono przebiegać tak:
1. Host A wysyła segment FIN ACK do hosta B
2. Host B potwierdza wysyłając segment ACK do hosta B
3. Host B wysyła segment FIN ACK do hosta A.
4. Host A potwierdza wysyłając segmnet ACK do hosta B.
Dopuszcza się również awaryjne przerwanie połączenia poprzez przesłanie pakietu z flagą RST. Pakiet taki nie wymaga potwierdzenia.

Całą naszą sesję TCP można zobaczyć na poniższym rysunku:



Możemy teraz zobrazować proces enkapsulacji na przykładzie ramki czwartej - tam gdzie serwer wysyła dane. Wszystkie dane w ramce zaprezentowane są w postaci liczb szesnastkowych.

Na początku mamy dane warstwy aplikacji:
48 65 6c 6c 6f - tekst "Hello"

Następnie dodawany jest nagłówek TCP warstwy transportowej:
1b 54 9d f5 56 19 59 30 6b 0e bb 57 50 18 ff ff 7b 83 00 00
1b 54 - port nadawcy = 6996
9d f5 - port odbiorcy = 40437
56 19 59 30 - numer sekwencyjny Seq = ‭1444501808
6b 0e bb 57 - numer potwierdzenia Ack = ‭1796127575‬
5 - długość nagłówka 5x4 bajty = 20 bajtów
0 18 - flagi (PSH, ACK) 000 000011000 
ff ff - szerokość okna = 65535
7b 83 - suma kontrolna
00 00 - wskaźnik priorytetu
Powstaje segment TCP.

Potem dodawany jest nagłówek IPv4 warstwy internetowej:
45 00 00 2d 02 d1 40 00 80 06 76 81 c0 a8 00 17 c0 a8 00 11
4 - wersja protokołu IP = IPv4
5 - długość nagłówka 5x4 bajty = 20 bajtów
00 - Differentiated Services Field
00 2d - długość całkowita pakietu = 45
02 d1 - identyfikator
40 00 - flagi (don't fragment) + przemieszczenie fragmentacji
80 - Time To Live = 128
06 - protokół = 6 = TCP
76 81 - suma kontrolna nagłówka
c0 a8 00 17 - źródłowy adres IP = 192.168.0.23
c0 a8 00 11 - docelowy adres IP = 192.168.0.17

Powstaje pakiet IP.

Następnie dodawany jest nagłówek Ethernet warstwy dostępu do sieci:
00 21 63 23 55 d1 00 21 00 ae 81 e6 08 00
00 21 63 23 55 d1 - docelowy adres MAC
00 21 00 ae 81 e6 - źródłowy adres MAC
08 00 - typ = IPv4

Powstaje ramka ethernetowa.

Dodatkowe pojęcia

Numer portu warstwy transportowej - odpowiada za dostarczenie danych do właściwej aplikacji. Każda aplikacja w systemie operacyjnym posiada swój identyfikator jednoznacznie ją określający. Identyfikatorem tym jest numer portu aplikacji. Serwer WWW domyślnie pracuje na porcie 80/TCP, serwer pocztowy POP3 na porcie 110/TCP a serwer DNS na porcie 53/UDP.

Nie można uruchomić dwóch różnych serwerów (procesów) nasłuchujących na tym samym porcie. Funkcja bind() zwróci wtedy błąd 10048:
Windows Sockets Error Codes

Gniazdo sieciowe (ang. socket) to kombinacja adresu IP, numeru portu i użytego protokołu warstwy transportowej (np. TCP, UDP). Unikalna kombinacja tych trzech parametrów pozwala na zidentyfikowanie właściwego procesu, do którego wiadomość powinna być dostarczona.

Proces powiązywania aplikacji i gniazda jest nazywany przypisaniem (ang. binding).

Omawiany na powyższym przykładzie ruch w sieci został przechwycony za pomocą sniffera Wireshark , który jest darmowym i wolnym oprogramowaniem dla systemów z rodziny Linux, macOS i Windows.