logo

C'de Soket Programlama

Soket programlama birbirleriyle iletişim kurmak için bir ağdaki iki düğümü birbirine bağlamanın bir yoludur. Bir soket (düğüm) bir IP'deki belirli bir bağlantı noktasını dinlerken, diğer soket bir bağlantı oluşturmak için diğerine ulaşır. İstemci sunucuya ulaşırken sunucu dinleyici soketini oluşturur.
Soket programlama, anlık mesajlaşma uygulamalarında ikili akış ve belge işbirlikleri çevrimiçi akış platformlarında vb. yaygın olarak kullanılır.

Örnek

Bu C programında istemci/sunucu modelini göstermek için sunucu ile istemci arasında bir merhaba mesajı alışverişinde bulunuyoruz.

sunucu.c

C
#include  #include  #include  #include  #include  #include  #define PORT 8080 int main(int argc char const* argv[]) {  int server_fd new_socket;  ssize_t valread;  struct sockaddr_in address;  int opt = 1;  socklen_t addrlen = sizeof(address);  char buffer[1024] = { 0 };  char* hello = 'Hello from server';  // Creating socket file descriptor  if ((server_fd = socket(AF_INET SOCK_STREAM 0)) < 0) {  perror('socket failed');  exit(EXIT_FAILURE);  }  // Forcefully attaching socket to the port 8080  if (setsockopt(server_fd SOL_SOCKET  SO_REUSEADDR | SO_REUSEPORT &opt  sizeof(opt))) {  perror('setsockopt');  exit(EXIT_FAILURE);  }  address.sin_family = AF_INET;  address.sin_addr.s_addr = INADDR_ANY;  address.sin_port = htons(PORT);  // Forcefully attaching socket to the port 8080  if (bind(server_fd (struct sockaddr*)&address  sizeof(address))  < 0) {  perror('bind failed');  exit(EXIT_FAILURE);  }  if (listen(server_fd 3) < 0) {  perror('listen');  exit(EXIT_FAILURE);  }  if ((new_socket  = accept(server_fd (struct sockaddr*)&address  &addrlen))  < 0) {  perror('accept');  exit(EXIT_FAILURE);  }    // subtract 1 for the null  // terminator at the end  valread = read(new_socket buffer  1024 - 1);   printf('%sn' buffer);  send(new_socket hello strlen(hello) 0);  printf('Hello message sentn');  // closing the connected socket  close(new_socket);    // closing the listening socket  close(server_fd);  return 0; } 

istemci.c

C
#include    #include  #include  #include  #include  #define PORT 8080 int main(int argc char const* argv[]) {  int status valread client_fd;  struct sockaddr_in serv_addr;  char* hello = 'Hello from client';  char buffer[1024] = { 0 };  if ((client_fd = socket(AF_INET SOCK_STREAM 0)) < 0) {  printf('n Socket creation error n');  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(  'nInvalid address/ Address not supported n');  return -1;  }  if ((status  = connect(client_fd (struct sockaddr*)&serv_addr  sizeof(serv_addr)))  < 0) {  printf('nConnection Failed n');  return -1;  }    // subtract 1 for the null  // terminator at the end  send(client_fd hello strlen(hello) 0);  printf('Hello message sentn');  valread = read(client_fd buffer  1024 - 1);   printf('%sn' buffer);  // closing the connected socket  close(client_fd);  return 0; } 


Derleme



gcc client.c -o clientgcc server.c -o server


Çıkış

Client:Hello message sentHello from serverServer:Hello from clientHello message sent

Soket Programlamanın Bileşenleri

1. Soketler

Soketler ağ üzerinden diğer işlemlerle/düğümlerle iletişim kurmak üzere ağa erişmek için program tarafından kullanılan temel bileşenlerden biridir. Bu, İletişim için bir uç nokta görevi gören bir IP adresi ile bir bağlantı noktası numarasının birleşiminden ibarettir.
Örnek: 192.168.1.1:8080 burada iki nokta üst üste ile ayrılan iki kısım IP adresi(192.168.1.1) ve bağlantı noktası numarası (8080).

Soket Çeşitleri:

  • TCP Soketi (Akış Soketi): Güvenilir bağlantı tabanlı iletişim sağlar (örn. TCP protokolü ).
  • UDP Soketi (Datagram Soketi): Bağlantısız iletişimi daha hızlı sağlar ancak güvenilmezdir (ör. UDP protokolü ).

2. İstemci-Sunucu Modeli

istemci-sunucu modeli Soket programlamada kullanılan, istemci ve sunucunun bilgi veya hizmet alışverişinde bulunmak üzere birbirleriyle etkileşime girdiği mimariyi ifade eder. Bu mimari, istemcinin hizmet istekleri göndermesine ve sunucunun bu hizmet isteklerini işlemesine ve yanıt göndermesine olanak tanır.

Sunucu ve İstemci Modeli için Durum Diyagramı

C'de Soket ProgramlamaSoketin sunucu ve istemci modeli için durum diyagramı

C'de soket programlama, ağ iletişimini yönetmenin güçlü bir yoludur.

Sunucu Tarafı İşlemi Oluşturma

Sunucu aşağıdaki adımlar kullanılarak oluşturulur:

neden java'da işaretleyici arayüzü

1. Soket Oluşturma

Bu adım, soket() işlevini kullanarak soketin oluşturulmasını içerir.

Parametreler:

  • çorap: soket tanımlayıcısı bir tam sayı (dosya tanıtıcısı gibi)
  • ihtisas: tamsayı iletişim alanını belirtir. Aynı ana bilgisayardaki işlemler arasındaki iletişim için POSIX standardında tanımlandığı gibi AF_ LOCAL kullanıyoruz. IPV4 ile bağlanan farklı ana bilgisayarlardaki işlemler arasında iletişim kurmak için, IPV6 ile bağlanan işlemler için AF_INET ve AF_I NET 6 kullanıyoruz.
  • tip: iletişim türü
    SOCK_STREAM: TCP(güvenilir bağlantı odaklı)
    SOCK_DGRAM: UDP(güvenilmez, bağlantısız)
  • protokol: İnternet Protokolü(IP) için protokol değeri 0'dır. Bu, bir paketin IP başlığındaki protokol alanında görünen sayının aynısıdır.(daha fazla ayrıntı için man protokolleri)
C
sockfd = socket(domain type protocol) 

2. Soket tercihini ayarlayın

Bu, sockfd dosya tanımlayıcısı tarafından belirtilen soket için seçeneklerin değiştirilmesine yardımcı olur. Bu tamamen isteğe bağlıdır ancak adresin ve bağlantı noktasının yeniden kullanılmasına yardımcı olur. Halihazırda kullanımda olan adres gibi hataları önler.

C
setsockopt(sockfd level optname optval socklen_t optlen); 

3. Bağla

Soket oluşturulduktan sonra bind() işlevi, soketi addr'de (özel veri yapısı) belirtilen adrese ve port numarasına bağlar. Örnek kodda sunucuyu localhost'a bağladık, dolayısıyla IP adresini belirtmek için INADDR_ANY'yi kullandık.

C++
bind(sockfd sockaddr *addr socklen_t addrlen); 

Parametreler:

  • çorap : Socket() işlevi kullanılarak oluşturulan soket dosyası tanımlayıcısı.
  • adres : Soketi bağlamak için IP adresini ve port numarasını içeren bir sockaddr yapısının işaretçisi.
  • addrlen : addr yapısının uzunluğu.

4. Dinleyin

Bu adımda sunucu, sunucu soketini pasif moda sokan ve istemcinin bağlantı kurmak için sunucuya yaklaşmasını bekleyen listen() işlevini kullanır. Biriktirme listesi, sockfd için bekleyen bağlantı kuyruğunun büyüyebileceği maksimum uzunluğu tanımlar. Kuyruk dolduğunda bir bağlantı isteği gelirse istemci, ECONNREFUSED göstergesini içeren bir hata alabilir.

C
listen(sockfd backlog); 

Parametreler :

  • çorap : Socket() işlevi kullanılarak oluşturulan soket dosyası tanımlayıcısı.
  • birikmiş iş yığını : Sunucu bir bağlantıyı kabul etmeyi beklerken, bekleyen bağlantıları tutan kuyruğun boyutunu temsil eden sayı.

5. Kabul et

Bu adımda sunucu, dinleme soketi için bekleyen bağlantılar kuyruğundan ilk bağlantı isteğini çıkarır sockfd, aşağıdaki komutu kullanarak yeni bir bağlı soket oluşturur: kabul etmek() işlevi çalıştırır ve bu sokete atıfta bulunan yeni bir dosya tanımlayıcı döndürür. Bu noktada istemci ve sunucu arasında bağlantı kurulur ve veri aktarımına hazır hale gelirler.

C
new_socket= accept(sockfd sockaddr *addr socklen_t *addrlen); 

Parametreler:

  • çorap : soket() ve bağlama() tarafından döndürülen soket dosyası tanımlayıcısı.
  • adres : istemcinin IP adresini ve port numarasını tutacak sockaddr yapısının işaretçisi.
  • addrlen : adres yapısının uzunluğunu belirten bir değişkenin işaretçisi.

6. Gönder/Al

Bu adımda sunucu istemciye veri gönderebilir veya alabilir.

Göndermek(): istemciye veri göndermek için

C
send(sockfd *buf len flags); 

Parametreler:

  • çorap : Socket() işlevi tarafından döndürülen soket dosyası tanımlayıcısı.
  • devetüyü : gönderilecek verileri içeren arabelleğin işaretçisi.
  • sadece : gönderilecek verinin bayt sayısı.
  • bayraklar : Verilerin nasıl gönderildiğine ilişkin çeşitli seçenekleri belirten tamsayı, varsayılan davranış için genellikle 0 kullanılır.

Almak() : istemciden veri almak için.

C
recv( sockfd *buf len flags); 

Parametreler:

  • çorap : Socket() işlevi tarafından döndürülen soket dosyası tanımlayıcısı.
  • devetüyü : saklanacak verileri içeren arabelleğin işaretçisi.
  • sadece : gönderilecek verinin bayt sayısı.
  • bayraklar : Verilerin nasıl gönderildiğine ilişkin çeşitli seçenekleri belirten tamsayı, varsayılan davranış için genellikle 0 kullanılır.

6. Kapat

Bilgi alışverişi tamamlandıktan sonra sunucu close() fonksiyonunu kullanarak soketi kapatır ve sistem kaynaklarını serbest bırakır.

C
close(fd); 

Parametreler:

  • fd: soketin dosya tanımlayıcısı.

İstemci Tarafı Süreç Oluşturma

İstemci tarafı işlemi oluşturmak için aşağıdaki adımları izleyin:

1. Soket bağlantısı

Bu adım, sunucunun soket oluşturma işlemiyle aynı şekilde gerçekleştirilen soketin oluşturulmasını içerir.

2. Bağlan

connect() sistem çağrısı, sockfd dosya tanımlayıcısı tarafından belirtilen soketi, addr tarafından belirtilen adrese bağlar. Sunucunun adresi ve portu adreste belirtilir.

C++
connect(sockfd sockaddr *addr socklen_t addrlen); 

Parametreler

  • çorap : Socket() işlevi tarafından döndürülen soket dosyası tanımlayıcısı.
  • adres : sunucunun IP adresini ve port numarasını içeren sockaddr yapısını gösteren işaretçi.
  • addrlen : adresin boyutu.

3. Gönder/Al

Bu adımda istemci, sunucunun istemciden veri göndermesine/almasına benzer şekilde send() ve recieve() işlevlerini kullanarak sunucuya veri gönderebilir veya alabilir.

4. Kapat

Bilgi alışverişi tamamlandıktan sonra istemcinin de oluşturulan soketi kapatması ve sunucunun yaptığı gibi close() işlevini kullanarak sistem kaynaklarını serbest bırakması gerekir.

Soket Programlamada Yaygın Sorunlar ve Çözümleri

  • Bağlantı Arızaları: Bağlantı hatalarını önlemek için istemcinin doğru ağa bağlanmaya çalıştığından emin olmalıyız. IP adresi ve bağlantı noktası .
  • Bağlantı Noktası Bağlama Hataları: Bu hatalar, bir bağlantı noktası başka bir uygulama tarafından zaten kullanıldığında ortaya çıkar; bu senaryoda, söz konusu bağlantı noktasına bağlanma başarısız olur. Farklı bir bağlantı noktası kullanmayı deneyin veya bağlantı noktasını kullanarak önceki uygulamayı kapatın.
  • Soketleri Engelleme: Varsayılan olarak yuvalar engelleniyor. Bu, istemci bağlantısı veya veri olmadığında kabul() veya recv() gibi çağrıların süresiz olarak bekleyeceği anlamına gelir. Gerekirse soketi engellemesiz moda ayarlayabilirsiniz.
Test Oluştur