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 sentSoket 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ı
Soketin 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)
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.
Csetsockopt(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.
Clisten(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.
Cnew_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
Csend(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.
Crecv( 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.
Cclose(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.