Unix Soketi - Çekirdek Fonksiyonlar

Bu bölüm, eksiksiz bir TCP istemcisi ve sunucusu yazmak için gereken temel yuva işlevlerini açıklar.

Aşağıdaki şema, tam İstemci ve Sunucu etkileşimini göstermektedir -

Soket İşlevi

Ağ G / Ç'yi gerçekleştirmek için, bir işlemin yapması gereken ilk şey, soket işlevini çağırmak, istenen iletişim protokolü türünü ve protokol ailesini vb. Belirtmektir.

#include <sys/types.h>
#include <sys/socket.h>

int socket (int family, int type, int protocol);

Bu çağrı, sonraki sistem çağrılarında kullanabileceğiniz bir soket tanımlayıcısı veya hata durumunda -1 döndürür.

Parametreler

family - Protokol ailesini belirtir ve aşağıda gösterilen sabitlerden biridir -

Aile Açıklama
AF_INET IPv4 protokolleri
AF_INET6 IPv6 protokolleri
AF_LOCAL Unix alan protokolleri
AF_ROUTE Yönlendirme Soketleri
AF_KEY Ket soketi

Bu bölüm IPv4 dışındaki diğer protokolleri kapsamaz.

type- İstediğiniz soket türünü belirtir. Aşağıdaki değerlerden birini alabilir -

Tür Açıklama
SOCK_STREAM Akış soketi
SOCK_DGRAM Datagram soketi
SOCK_SEQPACKET Sıralı paket soketi
SOCK_RAW Ham soket

protocol - Bağımsız değişken, aşağıda verilen belirli protokol türüne veya verilen aile ve tür birleşimi için sistemin varsayılanını seçmek için 0'a ayarlanmalıdır -

Protokol Açıklama
IPPROTO_TCP TCP aktarım protokolü
IPPROTO_UDP UDP taşıma protokolü
IPPROTO_SCTP SCTP taşıma protokolü

bağlantı Fonksiyonu

Connect işlevi, bir TCP sunucusu ile bağlantı kurmak için TCP istemci tarafından kullanılır.

#include <sys/types.h>
#include <sys/socket.h>

int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);

Bu çağrı, sunucuya başarılı bir şekilde bağlanırsa 0 döndürür, aksi takdirde hata durumunda -1 döndürür.

Parametreler

  • sockfd - Soket işlevi tarafından döndürülen bir soket tanımlayıcısıdır.

  • serv_addr - Hedef IP adresini ve bağlantı noktasını içeren sockaddr yapısına bir göstericidir.

  • addrlen - Sizeof (struct sockaddr) olarak ayarlayın.

bağlama İşlevi

Bağlama işlevi, bir sokete yerel protokol adresini atar. İnternet protokolleriyle, protokol adresi, 16 bitlik bir TCP veya UDP bağlantı noktası numarasıyla birlikte 32 bit IPv4 adresi veya 128 bit IPv6 adresinin birleşimidir. Bu işlev yalnızca TCP sunucusu tarafından çağrılır.

#include <sys/types.h>
#include <sys/socket.h>

int bind(int sockfd, struct sockaddr *my_addr,int addrlen);

Bu çağrı, adrese başarılı bir şekilde bağlanırsa 0 döndürür, aksi takdirde hata durumunda -1 döndürür.

Parametreler

  • sockfd - Soket işlevi tarafından döndürülen bir soket tanımlayıcısıdır.

  • my_addr - Yerel IP adresini ve bağlantı noktasını içeren sockaddr yapısının bir göstericisidir.

  • addrlen - Sizeof (struct sockaddr) olarak ayarlayın.

IP adresinizi ve bağlantı noktanızı otomatik olarak girebilirsiniz

Bağlantı noktası numarası için 0 değeri, sistemin rastgele bir bağlantı noktası seçeceği anlamına gelir ve IP adresi için INADDR_ANY değeri, sunucunun IP adresinin otomatik olarak atanacağı anlamına gelir.

server.sin_port = 0;  		     
server.sin_addr.s_addr = INADDR_ANY;

NOTE- 1024'ün altındaki tüm bağlantı noktaları ayrılmıştır. Diğer programlar tarafından kullanılmıyorsa, 1024'ün üzerinde ve 65535'in altında bir bağlantı noktası ayarlayabilirsiniz.

dinle İşlevini

Dinlemek işlevi yalnızca TCP sunucusu tarafından denir ve iki eylemleri gerçekleştirir edilir -

  • Listen işlevi, bağlantısız bir soketi pasif bir sokete dönüştürerek çekirdeğin bu sokete yönlendirilen gelen bağlantı isteklerini kabul etmesi gerektiğini belirtir.

  • Bu işlevin ikinci argümanı, çekirdeğin bu soket için sıraya koyması gereken maksimum bağlantı sayısını belirtir.

#include <sys/types.h>
#include <sys/socket.h>

int listen(int sockfd,int backlog);

Bu çağrı başarılı olduğunda 0 döndürür, aksi takdirde hata durumunda -1 döndürür.

Parametreler

  • sockfd - Soket işlevi tarafından döndürülen bir soket tanımlayıcısıdır.

  • backlog - İzin verilen bağlantı sayısıdır.

kabul İşlevini

Kabul işlevi tamamlanmış bağlantı sıranın önünden sonraki tamamlanmış bağlantıyı dönmek için bir TCP sunucu tarafından çağrılır. Aramanın imzası aşağıdaki gibidir -

#include <sys/types.h>
#include <sys/socket.h>

int accept (int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);

Bu çağrı, başarı durumunda negatif olmayan bir tanımlayıcı döndürür, aksi takdirde hata durumunda -1 döndürür. Döndürülen tanımlayıcının bir istemci soket tanımlayıcısı olduğu varsayılır ve istemci ile iletişim kurmak için tüm okuma-yazma işlemleri bu tanımlayıcı üzerinde yapılacaktır.

Parametreler

  • sockfd - Soket işlevi tarafından döndürülen bir soket tanımlayıcısıdır.

  • cliaddr - İstemci IP adresini ve bağlantı noktasını içeren sockaddr yapısına bir göstericidir.

  • addrlen - Sizeof (struct sockaddr) olarak ayarlayın.

gönderme Fonksiyonu

Gönderme işlevi akış soketi veya BAĞLANTILI veri yuva üzerinden veri göndermek için kullanılır. BAĞLANTISIZ datagram soketleri üzerinden veri göndermek istiyorsanız, sendto () işlevini kullanmalısınız.

Veri göndermek için write () sistem çağrısını kullanabilirsiniz. İmzası aşağıdaki gibidir -

int send(int sockfd, const void *msg, int len, int flags);

Bu çağrı, gönderilen bayt sayısını döndürür, aksi takdirde hata durumunda -1 döndürür.

Parametreler

  • sockfd - Soket işlevi tarafından döndürülen bir soket tanımlayıcısıdır.

  • msg - Göndermek istediğiniz verilere bir göstericidir.

  • len - Göndermek istediğiniz verinin uzunluğudur (bayt cinsinden).

  • flags - 0 olarak ayarlanmıştır.

recv İşlevi

Recv işlevi, akım priz veya BAĞLI veri yuva üzerinden veri almak için kullanılır. BAĞLANTISIZ datagram soketleri üzerinden veri almak istiyorsanız recvfrom () kullanmalısınız.

Verileri okumak için read () sistem çağrısını kullanabilirsiniz. Bu çağrı, yardımcı işlevler bölümünde açıklanmıştır.

int recv(int sockfd, void *buf, int len, unsigned int flags);

Bu çağrı, arabelleğe okunan bayt sayısını döndürür, aksi takdirde hata durumunda -1 döndürür.

Parametreler

  • sockfd - Soket işlevi tarafından döndürülen bir soket tanımlayıcısıdır.

  • buf - Bilginin okunacağı ara bellektir.

  • len - Tamponun maksimum uzunluğudur.

  • flags - 0 olarak ayarlanmıştır.

sento İşlevi

Sento işlevi bağlantısız veri yuva üzerinden veri göndermek için kullanılır. İmzası aşağıdaki gibidir -

int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);

Bu çağrı gönderilen bayt sayısını döndürür, aksi takdirde hata durumunda -1 döndürür.

Parametreler

  • sockfd - Soket işlevi tarafından döndürülen bir soket tanımlayıcısıdır.

  • msg - Göndermek istediğiniz verilere bir göstericidir.

  • len - Göndermek istediğiniz verinin uzunluğudur (bayt cinsinden).

  • flags - 0 olarak ayarlanmıştır.

  • to - Verilerin gönderilmesi gereken ana bilgisayar için sockaddr yapılandırmak için bir göstericidir.

  • tolen - Sizeof (struct sockaddr) olarak ayarlanır.

recvfrom İşlevi

Recvfrom fonksiyonu bağlı olmayan veri yuva veri almak için kullanılır.

int recvfrom(int sockfd, void *buf, int len, unsigned int flags struct sockaddr *from, int *fromlen);

Bu çağrı, arabelleğe okunan bayt sayısını döndürür, aksi takdirde hata durumunda -1 döndürür.

Parametreler

  • sockfd - Soket işlevi tarafından döndürülen bir soket tanımlayıcısıdır.

  • buf - Bilginin okunacağı ara bellektir.

  • len - Tamponun maksimum uzunluğudur.

  • flags - 0 olarak ayarlanmıştır.

  • from - Verilerin okunması gereken ana bilgisayar için sockaddr yapılandırmak için bir göstericidir.

  • fromlen - Sizeof (struct sockaddr) olarak ayarlanır.

yakın İşlevi

Yakın fonksiyon istemci ve sunucu arasındaki iletişimi kapatmak için kullanılır. Sözdizimi aşağıdaki gibidir -

int close( int sockfd );

Bu çağrı başarılı olduğunda 0 döndürür, aksi takdirde hata durumunda -1 döndürür.

Parametreler

  • sockfd - Soket işlevi tarafından döndürülen bir soket tanımlayıcısıdır.

kapatma Fonksiyonu

Kapatma işlevi incelikle istemci ve sunucu arasındaki iletişim kapatmak için kullanılır. Bu işlev, kapatma işlevine kıyasla daha fazla kontrol sağlar. Aşağıda, kapatma sözdizimi verilmiştir -

int shutdown(int sockfd, int how);

Bu çağrı başarılı olduğunda 0 döndürür, aksi takdirde hata durumunda -1 döndürür.

Parametreler

  • sockfd - Soket işlevi tarafından döndürülen bir soket tanımlayıcısıdır.

  • how - Rakamlardan birini yazın -

    • 0 - almaya izin verilmediğini gösterir,

    • 1 - göndermeye izin verilmediğini ve

    • 2- hem göndermeye hem de almaya izin verilmediğini gösterir. Ne zaman nasıl 2 olarak ayarlandığında, bu yakın olarak aynı şey ().

seçme İşlevi

Seçme fonksiyonu yazma, okuma için hazır hazır, veya beklemede bir hata durumunda, belirtilen dosya tanımlayıcıları ettiğini gösterir.

Bir uygulama recv veya recvfrom çağırdığında , o sokete veri gelene kadar engellenir. Bir uygulama, gelen veri akışı boşken başka yararlı işlemler yapıyor olabilir. Diğer bir durum, bir uygulamanın birden çok soketten veri almasıdır.

Giriş kuyruğunda veri bulunmayan bir sokette recv veya recvfrom çağırmak , diğer soketlerden anında veri alınmasını engeller. Select işlev çağrısı, programın tüm soket tutamaçlarını engellemeyen okuma ve yazma işlemleri için uygun olup olmadıklarını görmek için sorgulamasına izin vererek bu sorunu çözer.

Aşağıda Verilen yazılış biçimi seçin -

int select(int  nfds, fd_set  *readfds, fd_set  *writefds, fd_set *errorfds, struct timeval *timeout);

Bu çağrı başarılı olduğunda 0 döndürür, aksi takdirde hata durumunda -1 döndürür.

Parametreler

  • nfds- Test edilecek dosya tanımlayıcılarının aralığını belirtir. Select () işlevi, 0 ila nfds-1 aralığındaki dosya tanımlayıcılarını test eder.

  • readfds- Girişte okunmaya hazır olup olmadığı kontrol edilecek dosya tanımlayıcılarını ve çıktıda hangi dosya tanımlayıcılarının okumaya hazır olduğunu belirten fd_set türünde bir nesneye işaret eder. Boş bir küme belirtmek için NULL olabilir.

  • writefds- Girdi üzerinde, yazmaya hazır olup olmadığı kontrol edilecek dosya tanımlayıcılarını ve çıktıda hangi dosya tanımlayıcılarının yazmaya hazır olduğunu belirten fd_set türünde bir nesneye işaret eder. Boş bir küme belirtmek için NULL olabilir.

  • exceptfds- Girdi üzerinde, bekleyen hata durumları için kontrol edilecek dosya tanımlayıcılarını belirten fd_set türünde bir nesneye işaret eder ve çıktıda, hangi dosya tanımlayıcılarının bekleyen hata koşullarının olduğunu belirtir. Boş bir küme belirtmek için NULL olabilir.

  • timeout- Select çağrısının, kullanılabilir bir I / O işlemi için tanımlayıcıları ne kadar süreyle yoklaması gerektiğini belirten bir timeval yapısına işaret eder. Zaman aşımı değeri 0 ise, seçim hemen dönecektir. Zaman aşımı bağımsız değişkeni NULL ise, en az bir dosya / yuva tanıtıcısı kullanılabilir bir G / Ç işlemi için hazır olana kadar seçim engellenecektir. Aksi takdirde , zaman aşımı süresi geçtikten sonra VEYA en az bir dosya / soket tanımlayıcısı bir G / Ç işlemi için hazır olduğunda select dönecektir.

Select'in dönüş değeri, G / Ç için hazır olan dosya tanımlayıcı kümelerinde belirtilen tutamaçların sayısıdır. Zaman aşımı alanı tarafından belirlenen süre sınırına ulaşılırsa, 0 döndürülmesini seçin. Aşağıdaki makrolar, bir dosya tanımlayıcı kümesini işlemek için mevcuttur -

  • FD_CLR(fd, &fdset)- fdset dosya tanımlayıcı kümesindeki fd dosya tanımlayıcısının bitini temizler .

  • FD_ISSET(fd, &fdset)- fd dosya tanımlayıcısının biti , fdset ile gösterilen dosya tanımlayıcı kümesinde , aksi takdirde 0 olarak ayarlanmışsa, sıfır olmayan bir değer döndürür .

  • FD_SET(fd, &fdset) - fdset dosya tanımlayıcı kümesindeki fd dosya tanımlayıcısının bitini ayarlar.

  • FD_ZERO(&fdset) - fdset dosya tanımlayıcı kümesini tüm dosya tanımlayıcıları için sıfır bit olacak şekilde başlatır.

Bu makroların davranışı, fd argümanı 0'dan küçükse veya FD_SETSIZE'a eşit veya ondan büyükse tanımsızdır.

Misal

fd_set fds;

struct timeval tv;

/* do socket initialization etc.
tv.tv_sec = 1;
tv.tv_usec = 500000;

/* tv now represents 1.5 seconds */
FD_ZERO(&fds);

/* adds sock to the file descriptor set */
FD_SET(sock, &fds); 

/* wait 1.5 seconds for any data to be read from any single socket */
select(sock+1, &fds, NULL, NULL, &tv);

if (FD_ISSET(sock, &fds)) {
   recvfrom(s, buffer, buffer_len, 0, &sa, &sa_len);
   /* do something */
}
else {
   /* do something else */
}