logo

Programare socket în C/C++

În lumea de astăzi, rețelele de calculatoare joacă un rol important în domeniul transferului de date. Este un subiect pe care fiecare programator ar trebui să-l cunoască. În cadrul rețelei de calculatoare, programarea socket-urilor este unul dintre cele mai importante subiecte din lumea programării. În acest subiect, ne propunem să discutăm despre programarea socket-urilor și a metodei diferite de programare a socket-ului care este implementată în C++.

În C++, programarea socket este o metodă care combină două sau mai multe noduri între ele într-o rețea, astfel încât nodurile să poată partaja datele fără nicio pierdere a datelor. În această legătură, un nod ascultă un port care este conectat la o anumită adresă IP. Când clientul ajunge la server, serverul creează ascultătorul de socket.

Ce este o priză?

Să înțelegem despre priză vorbind exemplul în timp real. O priză este un tip de mediu care asigură o conexiune între două dispozitive. Priza poate fi fie un încărcător de telefon care asigură conexiunea între priză și telefon sau telefon și acel laptop. Cu ajutorul unei prize, diferite aplicații sunt atașate la rețeaua locală cu porturi diferite. De fiecare dată când socket-ul este creat, serverul specifică programul, iar acel program specifică socket-ul și adresa de domeniu.

Socket-ul este un tip de mecanism care este folosit pentru a face schimb de date între diferite procese. Aici aceste procese sunt fie prezente în dispozitive diferite, fie în același dispozitiv care sunt conectate printr-o rețea. Odată ce conexiunea pentru soclu este creată, atunci datele pot fi trimise în ambele direcții și continuă până când unul dintre punctele finale închide conexiunea.

Programare socket în C/C++

Procedura în Comunicarea Client-Server

Există câteva proceduri pe care trebuie să le respectăm pentru a stabili comunicarea client-server. Acestea sunt după cum urmează.

    Priză:Cu ajutorul unei prize, putem crea o nouă comunicare.Lega:Cu ajutorul acestui lucru putem, putem atașa adresa locală cu priza.Asculta:Cu acest ajutor; putem accepta conexiunea.Accept:Cu acest ajutor; putem bloca conexiunea de intrare până la sosirea cererii.Conectați:Cu acest ajutor; putem încerca să stabilim conexiunea.Trimite:Cu ajutorul acestuia; putem trimite datele prin rețea.A primi:Cu acest ajutor; putem primi datele prin rețea.Închide:Cu ajutorul acestuia, putem elibera conexiunea din rețea.

Etape pentru crearea socket-ului serverului

Există câteva etape prin care putem crea socket-ul pentru server. Acestea sunt după cum urmează.

    int socketcr:Socket (domeniu, tip, protocol)Socketcr:Este un tip întreg și este ca un handler de fișiere.Domeniu:Este un domeniu de comunicare și este de tip întreg.Tip:Este un tip de comunicare.SOCK_DGRAM:Este un tip de UDP care nu este de încredere și fără conexiune.Protocol:Este folosit pentru a atribui valoarea protocolului pentru adresa IP, care este 0. Valoarea protocolului este similară cu valoarea care apare în câmpul de protocol al antetului IP al buzunarului.

Ce este o conexiune?

O conexiune este un tip de relație între două mașini în care cele două software-uri sunt cunoscute unul despre celălalt. Aceste două programe software știu să stabilească o conexiune unul cu celălalt; cu alte cuvinte, putem spune că aceste două softuri știu să trimită biții prin rețea. O conexiune a prizei înseamnă că cele două mașini ar trebui să cunoască toate informațiile între ele, cum ar fi numărul de telefon, adresa IP și portul TCP.

Un socket este un tip de obiect care este similar cu fișierul care permite programului să accepte conexiunea de intrare și să le permită să trimită sau să primească conexiunea de intrare. De asemenea, este un tip de resursă atribuită procesului serverului.

Serverul poate crea socket-ul cu ajutorul socket-ului (). Acest soclu nu poate fi partajat cu niciun alt procesor.

    Setsockopt:Cu ajutorul Setsockopt, putem manipula diferitele opțiuni ale socket-ului, la care se face referire de descriptorul de fișier al socket-ului. Acest proces este complet opțional. Cu ajutorul Setsockopt, putem reutiliza portul și adresa clientului și serverului. Când serverul dă eroarea „adresă deja utilizată”, o putem preveni cu ajutorul Setsockopt.Lega:Putem lega priza cu adresa si portul cu ajutorul functiei bind. Această operație se face după crearea soclului. De exemplu, dacă încercăm să legăm serverul cu gazda locală, atunci folosim INADDR_ANY pentru a defini adresa IP a serverului.Asculta:Putem realiza o priză pentru modul de conectare cu ajutorul funcției de ascultare (). Un exemplu de priză pentru modul de conectare este SOCK_STREAM. Acest lucru poate fi definit prin argumentul socket. Acesta este utilizat pentru a accepta conexiunea de intrare, pentru a efectua operația de coadă pentru conexiunea de intrare și pentru a efectua întârzierea conexiunii de intrare. Când o conexiune de intrare solicită serverului de confirmare, soclul este pus în modul pasiv. Parametrul backlog al serverului se referă la faptul că nu poate permite mai mult de o conexiune simultan la server. Dacă a venit o conexiune de intrare și coada este plină, atunci serverul furnizează eroarea cu indicația „ECONNRFUSED”. Cu ajutorul listen(), conexiunea de intrare este în așteptare, iar când coada este goală, apelează la server toate conexiunile de intrare.Accept:Cu ajutorul apelului de sistem accept(); putem realiza soclul bazat pe conexiune. Unele prize bazate pe conexiune sunt SOCK_STREAM și SOCK_SEQPACKET. Extrage toate conexiunile de intrare care vin primele și permite cererii lor să ajungă la server. Lista nou conectată nu este capabilă să asculte cu ajutorul unui alt argument pentru crearea noii prize.

Etape pentru Client

    Conexiune priză:Este exact aceeași cu metoda de creare a serverului.Conectați:Putem iniția o conexiune la socket cu ajutorul apelului de sistem connect(). Dacă parametrul pentru socket este un tip de SOCK_DGRAM, atunci putem defini datagrama ca permanentă cu ajutorul connect(). Dacă socket-ul este de tip SOCK_STREAM, atunci putem încerca să facem o altă conexiune pentru server. Cu ajutorul funcției connect(), putem crea și o conexiune pentru asociația străină. Dacă socket-ul nu este legat, atunci sistemul atribuie valoarea unică asociației locale. Când apelurile de sistem sunt finalizate cu succes, priza este gata să trimită sau să primească orice tip de date.Trimite primește:Funcțiile send() și recv() pot efectua operația de mai jos.
  • Soclul pe care datele pot fi comunicate între ele.
  • Bufferul de stocare poate stoca date despre adresă, cum ar fi addr_of_data și addr_of_buffer.
  • Se ocupă de dimensiunea bufferului, cum ar fi len_of_data și len_of_buffer.
  • Se ocupă de steag care spune cum vor fi trimise datele.

Pași pentru a stabili conexiunea în priză

Stabilește o conexiune între diferiții clienți și server. Dar atât clientul, cât și serverul se pot ocupa de conexiunea socket. Fiecare proces trebuie să stabilească o conexiune pentru propria priză.

Pașii implicați în stabilirea unui socket pe partea clientului sunt următorii:

  • Acesta creează un socket cu ajutorul unui apel de sistem socket().
  • Apoi trebuie să ne conectăm cu adresa de socket a serverului cu ajutorul unui apel system().
  • Apoi trebuie să trimitem și să primim datele. Putem face acest lucru în diferite moduri. putem face această funcție read() și write().

Pașii implicați în stabilirea unui socket pe partea serverului sunt următorii:

  • Mai întâi creează un socket cu ajutorul unui apel de sistem socket().
  • Apoi leagă socket-ul la o adresă cu ajutorul apelului de sistem bind(). O adresă constă dintr-un număr de port pentru soclul serverului din mașina gazdă.
  • Apoi ascultă conexiunea cu ajutorul apelului de sistem de ascultare ().
  • Apoi serverul acceptă conexiunea de intrare cu ajutorul apelului de sistem accept(). De asemenea, blochează toate comenzile primite până când un client este conectat la un server.
  • Apoi începe procesul de trimitere și primire a datelor.

Conectarea mai multor clienți fără multithreading

Există diverse exemple în care vedem cum un singur utilizator se poate conecta la server. În lumea programării de astăzi, mai mulți utilizatori sunt conectați la server cu prize diferite.

Există diferite moduri de a realiza acest lucru. Una dintre ele este multithreading. Cu ajutorul multithreading-ului, putem realiza acest lucru. Putem implementa un proces multithreading cu ajutorul funcției select().

Exemplu:

Cod pentru client:

 // Client side C/C++ program to demonstrate Socket // programming #include #include #include #include #include #define PORT 8080 int main(int argc, char const* argv[]) { int sock = 0, valread, client_fd; struct sockaddr_in serv_addr; char* hello = &apos;Hello from client&apos;; char buffer[1024] = { 0 }; if ((sock = socket(AF_INET, SOCK_STREAM, 0)) <0) 0 8080 { printf('
 socket creation error 
'); return -1; } serv_addr.sin_family="AF_INET;" serv_addr.sin_port="htons(PORT);" convert ipv4 and ipv6 addresses from text to binary form if (inet_pton(af_inet, '127.0.0.1', &serv_addr.sin_addr) <="0)" printf( '
invalid address not supported ((client_fd="connect(sock," (struct sockaddr*)&serv_addr, sizeof(serv_addr))) 0) printf('
connection failed send(sock, hello, strlen(hello), 0); printf('hello message sent
'); valread="read(sock," buffer, 1024); printf('%s
', buffer); closing the connected close(client_fd); 0; code for server: server side c c++ program demonstrate programming #include #define port int main(int argc, char const* argv[]) server_fd, new_socket, valread; struct sockaddr_in address; opt="1;" addrlen="sizeof(address);" buffer[1024]="{" }; char* hello="Hello from server" ; creating file descriptor ((server_fd="socket(AF_INET," sock_stream, 0)) perror('socket failed'); exit(exit_failure); forcefully attaching (setsockopt(server_fd, sol_socket, so_reuseaddr | so_reuseport, &opt, sizeof(opt))) perror('setsockopt'); address.sin_family="AF_INET;" address.sin_addr.s_addr="INADDR_ANY;" address.sin_port="htons(PORT);" (bind(server_fd, sockaddr*)&address, sizeof(address)) perror('bind (listen(server_fd, 3) perror('listen'); ((new_socket="accept(server_fd," (socklen_t*)&addrlen)) perror('accept'); send(new_socket, close(new_socket); listening shutdown(server_fd, shut_rdwr); pre> <p> <strong>Compiling:</strong> </p> <img src="//techcodeview.com/img/c-tutorial/33/socket-programming-c-c-2.webp" alt="Socket Programming in C/C++"> <p> <strong>Output:</strong> </p> <img src="//techcodeview.com/img/c-tutorial/33/socket-programming-c-c-3.webp" alt="Socket Programming in C/C++"> <h2>Uses of Socket Programming</h2> <p>Socket programs are used to communicate between various processes, usually running on different systems. It is mostly used to create a client-server environment. This post provides the various functions used to create the server and client program and an example program.</p> <p>In the example, the client program sends a file name to the server, and the server sends the contents of the file back to the client. Socket programming usually pertains to basic communication protocols like TCP/UDP and raw sockets like ICMP. These protocols have a small communication overhead when compared to underlying protocols such as HTTP/DHCP/SMTP etc.</p> <p> <strong>Some of the basic data communications between the client and server are:</strong> </p> <ul> <li>File Transfer: Sends name and gets a file.</li> <li>Web Page: Sends URL and gets a page.</li> <li>Echo: Sends a message and gets it back.</li> </ul> <h2>Disadvantages</h2> <ul> <li>C++ can establish communication only with the machine requested and not with any other machine on the network.</li> <li>Sockets allow only raw data to be sent. This means that the client and server need mechanisms to interpret the data.</li> </ul> <hr></0)>