Gniazdo klient telnet
Transkrypt
Gniazdo klient telnet
Plan wykładu 1. Model TCP/IP ● protokoły warstwy transportowej: UDP, TCP, ● połączenie i rozłączenie w TCP. 2. Programowanie z wykorzystaniem gniazd. ● usługai DATETIME, TIME, ECHO. 3. Popularne aplikacje TCP/IP – poczta elektroniczna ● poczta elektroniczna: protokoły SMTP, POP, IMAP. 1 Protokół UDP UDP (User Datagram Protocol). [RFC 768] Protokół obsługi bezpołączeniowej procesów użytkownika. Nie daje gwarancji, że pakiety (datagramy) dotrą do wyznaczonego celu. Może korzystać zarówno z IPv4 oraz IPv6. 2 Protokół TCP TCP (Transmission Control Protocol). [RFC 793] ● wykorzystuje połączenie między klientem i serwerem, ● zapewnia niezawodność przesyłu danych – potwierdzenia, szacowanie czasu powrotu (round-trip time), ● ustala kolejność danych – numeracja segmentów, ● steruje przepływem – nadawca nie może spowodować przepełnienie bufora odbiorcy, ● zapewnia połączenie, które jest w pełni dwukierunkowe (full-duplex). Jest stosowany w większości internetowych programów użytkowych. Może korzystać zarówno z IPv4 oraz IPv6. 3 Ustanawianie połączenia TCP Uzgadnianie trójfazowe (three-way handshake). 1. Serwer przygotowuje się na przyjęcie połączenia – otwarcie bierne. 2. Klient rezerwuje gniazdo za pomocą a następnie rozpoczyna otwarcie aktywne - TCP wysyła segment danych SYN (synchronize). 3. Serwer wysyła własny segment SYN zawierający potwierdzenie ACK (acknowledgment). 4. Klient potwierdza przyjęcie segmentu SYN od serwera. wi Pot 1 K+ J ie ze n erd N SY serwer potw SYN K ierd zeni e J+1 klient 4 Zakończenie połączenia TCP 1. Jeden punkt końcowy inicjuje zakończenie połączenia – zamknięcie aktywne. TCP wysyła segment FIN. 2. Drugi punkt wykonuje zamknięcie bierne – TCP potwierdza odbiór FIN. 3. Po pewnym czasie drugi punkt zamyka swoje połączenie – TCP wysyła segment FIN. 4. Pierwszy punkt potwierdza odbiór segmenty FIN. ie z en er d M FIN N wi Pot 1 N+ FIN drugi punkt Potw M+ ierdzen 1 ie pierwszy punkt 5 Numery portów Numerami portów zarządza IANA (Internet Assigned Numbers Authority). Wyróżniamy trzy grupy portów. ● porty ogólne (well-known), numery z zakresu 0 – 1023, np.: HTTP 80, FTP 21, SMTP 25. ● porty zarejestrowane (registered), numery 1024 – 49151. np.: X-Windows 6000-6063, MySQL 3036. ● porty dynamiczne 49152 – 65535, nie posiadają przyporządkowania do usług. 6 Programowanie z wykorzystaniem gniazd Utworzenie gniazda: int socket (int domain, int type, int protocol) domain – rodzina protokołów używana do komunikacji w sieci, zdefiniowana w pliku <sys/socket.h> np.: PF_UNIX, PF_LOCAL, PF_INET, PF_INET6, PF_IPX. type – rodzaj komunikacji np.: SOCK_STREAM, SOCK_DGRAM, SOCK_RDM. protocol – protokół transmisji wykorzystywany przez gniazdo. Wartość zwracana: deskryptor gniazda lub -1 w przypadku błędu. Pliki nagłówkowe <sys/socket.h>, <sys/types.h>. 7 Programowanie z wykorzystaniem gniazd Połączenie poprzez gniazdo: int connect (int sock, const struct sockaddr *serv_addr, int len) sock – deskryptor gniazda uzyskany funkcją socket. serv_addr – wskaźnik do struktury opisującej punk docelowy połączenia. len – długość struktury wskazywanej przez serv_addr. Wartość zwracana: 0 w przypadku powodzenia, -1 w przypadku błędu. Pliki nagłówkowe <sys/socket.h>, <sys/types.h>. 8 Programowanie z wykorzystaniem gniazd Zamknięcie połączenia (gniazda): int shutdown (int sock, int how) sock – deskryptor gniazda uzyskany funkcją socket. how – sposób zamknięcia połączenia np.: SHUT_RD, SHUT_WR, SHUT_RDWR. Wartość zwracana: 0 w przypadku powodzenia, -1 w przypadku błędu. Pliki nagłówkowe <sys/socket.h>. 9 Programowanie z wykorzystaniem gniazd #include #include #include #include <sys/types.h> <sys/socket.h> <netinet/in.h> <netdb.h> #include <stdio.h> #include <errno.h> #include <string.h> int connectsock(char *host, char *service, char *protocol){ struct hostent *phe; struct servent *pse; struct protoent *ppe; struct sockaddr_in sin; int type, s; bzero((char*) &sin, sizeof(sin)); sin.sin_family = AF_INET; 10 Programowanie z wykorzystaniem gniazd if (pse = getservbyname(service, protocol)){ sin.sin_port = pse->s_port; }else if ((sin.sin_port = htons((u_short)atoi(service)))==0){ fprintf(stderr, "nieznana usluga: %s\n", service); return -1; } if (phe = gethostbyname(host)){ bcopy(phe->h_addr, (char *) &sin.sin_addr, phe->h_length); }else if ((sin.sin_addr.s_addr = inet_addr(host))==INADDR_NONE){ fprintf(stderr, "nieznany host: %s\n", host); return -1; } if ((ppe = getprotobyname(protocol))==NULL){ fprintf(stderr, "nieznany protokol: %s\n", protocol); return -1; } 11 Programowanie z wykorzystaniem gniazd if (strcmp(protocol, "udp")==0){ type = SOCK_DGRAM; }else{ type = SOCK_STREAM; } if ((s = socket(PF_INET, type, ppe->p_proto))<0){ fprintf(stderr, "nieznany protokol: %s\n", protocol); return -1; } } if (connect(s, (struct sockaddr *)&sin, sizeof(sin))<0){ fprintf(stderr, "nie moge ustanowic polaczenia z %s:%s %s\n", host, service, strerror(errno)); return -1; } return s; 12 Programowanie z wykorzystaniem gniazd #define LINELEN 100 int main(int argc, char **argv){ int s, n; char buf[LINELEN+1]; } if (argc<4){ printf("sposob uzycia: client serwer serwis protokol\n"); return 0; } s = connectsock(argv[1], argv[2], argv[3]); if(s<0) return 0; while ((n=read(s, buf, LINELEN))>0){ buf[n] = '\0'; fputs(buf, stdout); } if (shutdown(s, SHUT_RDWR)<0){ fprintf(stderr, "problem z zamknieciem polaczenia: %s\n", strerror(errno)); return 0; } return 1; 13 Programowanie z wykorzystaniem gniazd Przykładowe uruchomienie programu: client theta.uoks.uj.edu.pl daytime tcp Wynik działania: Tue Oct 14 15:27:25 2008 lista serwisów (usług, portów): /etc/services lista protokołów: /etc/protocols 14 Programowanie z wykorzystaniem gniazd - Java Pakiet (biblioteka): java.net Wybrane klasy: ● Socket – reprezentuje gnaizdo wykorzystywane do transmisji strumieniowej (TCP), istnieje wersja do transmisji szyfrowanej SSLSocket; ● DatagramSocket – gniazdo do transmisji datagramowej (UDP); ● InetAddress – adres IP, istnieją dwie klasy potomne: Inet4Address i Inet6Address; ● URL – Uniform Resource Locator, identyfikator zasobu w sieci opisujący sposób dostępu do niego np. http://www.if.uj.edu.pl/images/misc/ujlogo.gif, w ogólnym wypadku stosuje się klasę URI – Uniform Resource Identyficator. ● 15 Programowanie z wykorzystaniem gniazd - Java import java.io.InputStream; import java.net.Socket; public class Client { private static final int LINELEN = 100; public static void main(String[] args) { byte[] buffer = new byte[Client.LINELEN]; if (args.length<2) System.out.println("wywolanie java Client serwer port"); try { Socket sock = new Socket(args[0], Integer.parseInt(args[1])); InputStream in = sock.getInputStream(); while (in.read(buffer) > 0) System.out.println(new String(buffer)); sock.close(); } catch (Exception e) { e.printStackTrace(); } } } Wywołanie programu: javac Client.java java Client theta.uoks.uj.edu.pl 13 16 Programowanie z wykorzystaniem gniazd - C# using System; using System.IO; using System.Net.Sockets; public class socketexample { public static void Main() { try { TcpClient tcpclnt = new TcpClient(); tcpclnt.Connect("theta.uoks.uj.edu.pl",13); Stream stm = tcpclnt.GetStream(); byte[] bb = new byte[100]; int k = stm.Read(bb,0,100); for (int i = 0; i<k; i++) Console.Write(Convert.ToChar(bb[i])); tcpclnt.Close(); } catch (Exception e) { Console.WriteLine(e.StackTrace); } } } Wywołanie programu: mcs socketexample.cs mint socketexample.exe lub mono socketexample.exe 17 Programowanie z wykorzystaniem gniazd Perl: use IO::Socket; my $sock = new IO::Socket::INET (PeerAddr => 'theta.uoks.uj.edu.pl', PeerPort => '13', Proto => 'tcp', ); die "Nie można utworzyc gniazda: $!\n" unless $sock; while(<$sock>) print $_; close($sock); PHP: <?php $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); $result = socket_connect($socket, 'theta.uoks.uj.edu.pl', '13'); $out = socket_read($socket, 1024); echo $out; socket_close($socket); ?> 18 Programowanie z wykorzystaniem gniazd Python: import socket s = socket.socket ( socket.AF_INET, socket.SOCK_STREAM ) s.connect(("theta.uoks.uj.edu.pl", 13)) data = s.recv(1024) print data s.close() Ruby: require 'socket' print TCPSocket.open("theta.uoks.uj.edu.pl", "daytime").read 19 Usługa TIME Usługa TIME [RFC 868] służy do synchronizacji czasu pomiędzy komputerami w sieci. Czas jest przesyłany w postaci 32 bitowej liczby całkowitej określającej liczbę sekund od 1 stycznia 1900 roku np. C5 1B 77 8A. Usługa jest dostępna zarówno za pośrednictwem TCP i UDP poprzez port 37. Inne usługi wykorzystywane do synchronizacji czasu to NTP (Network Time Protocol) [RFC 1305] i jego odmiana SNTP (Simple Network Time Protocol) [RFC 1769]. 20 Klient usługi TIME (UDP) #include "connectsock.c" #define UNIXEPOCH 2208988800ul int main(int argc, char **argv){ int s; char msg[] = "ktora godzina?"; time_t now; if ((s = connectsock(argv[1], "time", "udp"))<0) return 0; write(s, msg, strlen(msg)); if (read(s, (char *)&now, sizeof(now))<0) return 0; else{ now = ntohl((u_long)now); now -= UNIXEPOCH; printf("%s\n", ctime(&now)); } if (shutdown(s, SHUT_RDWR)<0) return 0; return 1; } 21 Klient usługi TIME (TCP) import import import import java.io.InputStream; java.io.OutputStream; java.net.Socket; java.util.Date; public class private private private private TimeTCPClient { static final int PORT_TIME = 37; static final String QUERY = "Ktora godzina?"; static final int LINELEN = 5; static final long UNIXEPOCH = 2208988800L; public static void main(String[] args) { try { byte[] buffer = new byte[LINELEN]; Socket sock = new Socket(args[0], PORT_TIME); OutputStream os = sock.getOutputStream(); InputStream is = sock.getInputStream(); os.write(QUERY.getBytes()); 22 Klient usługi TIME (TCP) long time = 0; int l, i, j; for (l=0; l<4; l+=i){ i = is.read(buffer); for(j=0; j<i; j++){ time *= 256; time += (buffer[j] & 255); } } time -= UNIXEPOCH; time *= 1000; Date d = new Date(time); System.out.println(d); sock.close(); } catch (Exception e) { e.printStackTrace(); } } } 23 Klient usługi TIME (UDP) import import import import java.net.DatagramPacket; java.net.DatagramSocket; java.net.InetAddress; java.util.Date; public class private private private private TimeUDPClient { static final int PORT_TIME = 37; static final String QUERY = "Ktora godzina?"; static final int LINELEN = 5; static final long UNIXEPOCH = 2208988800L; public static void main(String[] args) { try { byte[] buffer = new byte[LINELEN]; DatagramSocket sock = new DatagramSocket(); DatagramPacket dp = new DatagramPacket( QUERY.getBytes(), 0, QUERY.length(), InetAddress.getByName(args[0]), PORT_TIME); 24 Klient usługi TIME (UDP) sock.send(dp); dp = new DatagramPacket(buffer, LINELEN); sock.receive(dp); long time = 0; int i; for (i=0; i<4; i++){ time *= 256; time += (buffer[i] & 255); } time -= UNIXEPOCH; time *= 1000; Date d = new Date(time); System.out.println(d); sock.close(); } catch (Exception e) { e.printStackTrace(); } } } 25 Usługa ECHO Usługa ECHO [RFC 347] odsyła klientowi wszystkie otrzymywane od niego dane. Interakcja trwa dopóki klient nie zakończy transmisji. Usługa ECHO jest wykorzystywana głównie do celów diagnostycznych, podobnie jak komenda ping. W przeciwieństwie do niej korzysta z protokołu TCP lub UDP. Do komunikacji wykorzystuje port 7. 26 Klient usługi ECHO (TCP) int main(int argc, char **argv){ int s, i, n1, n2; char buf[LINELEN+1]; if ((s = connectsock(argv[1], ”echo”, ”tcp”))<0) return 0; for(i=2; i<argc; i++){ n1 = write(s, argv[i], strlen(argv[i])); while (n1>0 && (n2=read(s, buf, LINELEN))>0){ buf[n2] = '\0'; n1 -= n2; fputs(buf, stdout); } fputs(”\n”, stdout); } if (shutdown(s, SHUT_RDWR)<0) return 0; return 1; } 27 Klient usługi ECHO (UDP) int main(int argc, char **argv){ int s, i, n; char buf[LINELEN+1]; if ((s = connectsock(argv[1], ”echo”, ”udp”))<0) return 0; for(i=2; i<argc; i++){ write(s, argv[i], strlen(argv[i])); if ((n=read(s, buf, LINELEN))>0){ buf[n] = '\0'; fputs(buf, stdout); } fputs(”\n”, stdout); } if (shutdown(s, SHUT_RDWR)<0) return 0; return 1; } 28 Klient usługi ECHO (TCP) import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; public class EchoTCPClient { private static final int PORT_ECHO = 7; private static final int LINELEN = 100; public static void main(String[] args) { byte[] buffer = new byte[LINELEN]; if (args.length<2){ System.out.println("wywolanie java EchoTCPClient serwer argument1 argument2 ..."); return; } try { Socket sock = new Socket(args[0], PORT_ECHO); OutputStream os = sock.getOutputStream(); InputStream in = sock.getInputStream(); 29 Klient usługi ECHO (TCP) int i, k, j; for (i=1; i<args.length; i++){ os.write(args[i].getBytes()); for(j=0; j<args[i].length(); j+=k){ k = in.read(buffer); System.out.print(new String(buffer, 0, k)); } System.out.println(); } sock.close(); } catch (Exception e) { e.printStackTrace(); } } } 30 Klient usługi ECHO (UDP) public class EchoUDPClient { private static final int PORT_ECHO = 7; private static final int LINELEN = 100; public static void main(String[] args) { try { byte[] buffer = new byte[LINELEN]; DatagramSocket sock = new DatagramSocket(); DatagramPacket dp; for (int i=1; i<args.length; i++){ dp = new DatagramPacket(args[i].getBytes(), 0, args[i].length(), InetAddress.getByName(args[0]), PORT_ECHO); sock.send(dp); dp = new DatagramPacket(buffer, LINELEN); sock.receive(dp); System.out.println(new String(dp.getData(), 0, dp.getLength())); } sock.close(); } catch (Exception e) { e.printStackTrace(); } } 31 } Poczta elektroniczna 1. Wysyłanie wiadomości e-mail – protokół SMTP (Simple Mail Transfer Protocol). 2. Odbiór wiadomości e-mail – propokół POP (Post Office Protocol) lub IMAP (Internet Mail Access Protocol). nadawca adresat serwer SMTP Serwer SMTP oraz POP lub IMAP 32 Protokół SMTP Protokół SMTP [RFC 2821, 821, 2554] jest wykorzystywany do wysyłania wiadomości e-mail. Port 25. Przykładowe połączenie: [serwer] 220 theta.uoks.uj.edu.pl ESMTP Sendmail 8.13.1/8.13.1; Mon, 11 Oct 2004 10:19:30 +0200 (CEST) [klient] EHLO [127.0.0.1]<CRLF> [serwer] 250-theta.uoks.uj.edu.pl Hello rhamnus.if.uj.edu.pl [149.156.74.158], pleased to meet you 250-ENHANCEDSTATUSCODES ... 250-AUTH LOGIN PLAIN ... 250 HELP [klient] AUTH PLAIN <BASE64(login<0x00>hasło)><CRLF> 33 Kodowanie Base64 Alfabet Base64 [RFC 1521] 0 1 2 3 4 5 6 7 A B C D E F G H 8 9 10 11 12 13 14 15 I J K L M N O P 16 17 18 19 20 21 22 23 Q R S T U V W X 24 25 26 27 28 29 30 31 Y Z a b c d e f 32 33 34 35 36 37 38 39 g h i j k l m n 40 41 42 43 44 45 46 47 o p q r s t u v 48 49 50 51 52 53 54 55 w x y z 0 1 2 3 56 57 58 59 60 61 62 63 4 5 6 7 8 9 + / (pad) = kodowanie: ala ma kota a (0x61) 01100001 (0x20) 00100000 l (0x6C) 01101100 k (0x6B) 01101011 a (0x61) (0x20) m (0x6D) a (0x61) 01100001 00100000 01101101 011000001 o (0x6F) t (0x74) a (0x61) 01101111 01110100 01100001 00 wynik: YWxhIG1hIGtvdGE= 34 Protokół SMTP [serwer] 235 2.0.0 OK Authenticated [klient] MAIL FROM:<[email protected]><CRLF> [serwer] 250 2.1.0 <[email protected]>... Sender ok [klient] RCPT TO:<[email protected]><CRLF> [serwer] 250 2.1.5 <[email protected]>... Recipient ok [klient] DATA<CRLF> [serwer] 354 Enter mail, end with "." on a line by itself 35 Protokół SMTP [klient] Date: Mon, 11 Oct 2004 10:19:24 +0200<CRLF> User-Agent: cokolwiek<CRLF> X-Accept-Language: en-us, en<CRLF> MIME-Version: 1.0<CRLF> From: ktokolwiek <[email protected]><CRLF> To: [email protected]<CRLF> Subject: jakis temat<CRLF> Content-Type: text/plain; charset=us-ascii<CRLF> Content-Transfer-Encoding: 7bit<CRLF><CRLF> tekst testowego maila<CRLF> .<CRLF> [serwer] 250 2.0.0 Message accepted for delivery [klient] QUIT<CRLF> [serwer] 221 2.0.0 theta.uoks.uj.edu.pl closing connection [serwer] Zakończenie połączenia. 36 Protokół POP Protokół POP [RFC 1939] jest używany do odbierania wiadomości e-mail znajdujących sie na serwerze. Port 110. Przykładowe połączenie: [serwer] +OK <processID.clock@hostname><CRLF> [klient] USER użytkownik<CRLF> [serwer] +OK<CRLF> [klient] PASS hasło<CRLF> [serwer] +OK<CRLF> [klient] STAT<CRLF> [serwer] 2 540<CRLF> //ilość wiadomości i ich rozmiar w oktetach 37 Protokół POP [klient] LIST<CRLF> [serwer] +OK<CRLF>1 120<CRLF>2 420<CRLF> [klient] LIST 3<CRLF> [serwer] +ERR ewentualnie powód błędu<CRLF> [klient] RETR 1<CRLF> [serwer] +OK<CRLF> <wiadomość e-mail><CRLF> [klient] DELE 1<CRLF> [serwer] +OK<CRLF> [klient] QUIT<CRLF> [serwer] +OK<CRLF> [serwer] Zakończenie połączenia 38 Protokół POP Inne komendy: ● RSET – odznacza wszystkie wiadomości przeznaczone do skasowania, ● NOOP – podtrzymuje połączenie, Komendy opcjonalne: ● TOP msg n – zwraca nagłówek oraz n początkowych lini wiadomości msg, ● UIDL msg – zwraca unikalny identyfikator wiadomości, ● APOP login kod – inny sposób autoryzacji. Pierwszy argument stanowi nazwę użytkownika, drugi to kod MD5 z połączenia <processID.clock@hostname> oraz ustalonego wcześniej wyrażenia znanego klientowi i serwerowi. 39 Kod MD5 MD5 (Message Digest Algorithm) [RFC 1321] oblicza 128 bitowy kod dla zbioru danych. Kod ten może być traktowany jak cyfrowy podpis (fingerprint) danych. Na podstawie kodu praktycznie nie można odtworzyć oryginalnych danych ponieważ wygenerowanie informacji posiadającej określony kod MD5 wymaga w praktyce 2128 operacji. 40 Protokół IMAP Protokół IMAP [RFC 2060] jest używany do przeglądania wiadomości e-mail przechowywanych na serwerze. Port 143. Przykładowe połączenie: [serwer] * OK IMAP4rev1<CRLF> [klient] 1 capability [serwer] * CAPABILITY IMAP4REV1 AUTH=LOGIN<CRLF> 1 OK CAPABILITY completed<CRLF> [klient] 2 authenticate login<CRLF> [serwer] + VXNlciBOYW1lAA==<CRLF> [klient] <Base64(użytkownik)><CRLF> [serwer] UGFzc3dvcmQA<CRLF> [klient] // Base64(User Name) <Base64(hasło)><CRLF> // Base64(Password) 41 Protokół IMAP [serwer] * OK [ALERT] Account expires in 14 day(s)<CRLF> inna autoryzacja: 2 login ”użytkownik” ”hasło”<CRLF> [klient] 3 select ”INBOX”<CRLF> [serwer] * FLAGS (\Draft \Answered \Flagged \Deleted \Seen \Recent) * 2 EXISTS * 0 RECENT * OK [UIDVALIDITY 1053533958] Ok 3 OK [READ-WRITE] Ok<CRLF> [klient] 4 UID FETCH 1:* (FLAGS)<CRLF> [serwer] * 1 FETCH (UID 1082 FLAGS (\Seen))<CRLF> * 2 FETCH (UID 1210 FLAGS (\Answered \Seen))<CRLF> 4 OK FETCH completed.<CRLF> 42 Protokół IMAP [klient] 5 UID FETCH 1210 (UID RFC822.SIZE BODY[])<CRLF> [serwer] * 283 FETCH (UID 1583 RFC822.SIZE 1180 BODY[] {1180}<CRLF> [serwer] <wiadomość email><CRLF> * 283 FETCH (FLAGS (\Seen \Recent))<CRLF> 5 OK FETCH completed.<CRLF> [klient] 6 LOGOUT<CRLF> [serwer] * BYE<CRLF> 6 OK logout completed.<CRLF> [serwer] Zakończenie połączenia. 43 Protokół IMAP Wiadomości na serwerze IMAP są grupowane w katalogach, podobnie jak pliki na dysku. Większość komend protokołu IMAP umożliwia poruszanie sie i wykonywanie odpowiednich operacji na tej strukturze: ● CREATE, DELETE, RENAME – operacje na katalogach (folderach), ● STORE, COPY, EXPUNGE – operacje na wiadomościach. ● X... - komendy rozszerzające funkcje protokołu IMAP. Odpowiedzi serwera: ● OK – operacja wykonana pomyślnie, ● NO – wystąpił problem, ● BAD – niewłaściwa komenda. 44 Popularne serwery pocztowe SMTP (Mail Transfer Agent): ● Sendmail (http://www.sendmail.org/), ● Qmail (http://www.qmail.org/), ● Postfix (http://www.postfix.org/), POP, IMAP ● courier-imap (http://www.courier-mta.org/imap/) Zarządzanie domenami wirtualnymi ● vpopmail (http://www.inter7.com/index.php?page=vpopmail), ● mysql (http://www.mysql.com). 45 Polecenie Telnet Protokół Telnet [RFC 854] jest/był wykorzystywany głównie pracy terminalowej poprzez port 23. Za pomocą programu klienta usługi Telnet można się także połączyć z dowolnym innym portem na serwerze, np. telnet theta.uoks.uj.edu.pl 25 Komendy wpisywane ze standardowego wejścia (klawiatury) są wysyłane bezpośrednio do wskazanej usługi (SMTP) na serwerze zdalnym. Odpowiedzi są kierowane na standardowe wyjście (ekran). 46 Podsumowanie Warstwa transportowa TCP/IP zawiera dwa protokoły: TCP i UDP. Programowanie w oparciu o interfejs gniazd korzysta ze standardowych mechanizmów wejścia-wyjścia zaimplementowanych w językach programowania i nie wymaga od programisty niskopoziomowej znajomości wykorzystywanych protokołów. Popularne usługi sieciowe takie jak poczta elektroniczna wykorzystują do komunikacji protokoły wysokiego poziomu, które umożliwiają komunikację pomiędzy komputerem klienckim i serwerem. Poczta elektroniczna najczęściej wykorzystuje do komunikacji następujące porty: 25 (SMTP), 110 (POP3) i 143 (IMAP). 47