Bantdışı Veri Aktarımı
Önceki Soketlerin Bağlantılarla Kullanılması Sonraki
Bantdışı Veri Aktarımı
Bağlantılı akımlar, sıradan veriye nazaran teslim edilme önceliğine sahip bantdışı veri aktarımına izin vermektedir. Bantdışı veri gönderiminin asıl kullanılma nedeni, özel durumlarda uyarı gönderme ihtiyacıdır. Bantdışı veri göndermek için send işlevini MSG_OOB bayrağıyla kullanınız (Bkz. Veri Gönderimi).
Bantdışı veriler yüksek öncelikle alınırlar çünkü alıcı işlem onu sırayla almak zorunda değildir; bir sonraki bantdışı veriyi okumak için, recv işlevini MSG_OOB bayrağıyla kullanınız (Bkz. Veri Alımı). Sıradan okuma işlemleri bantdışı veriyi okumazlar; sadece sıradan veriyi okurlar.
Soket, bantdışı verinin geldiğini görünce, kendi sürecine ya da süreç grubuna SIGURG sinyalini gönderir. Soket sahibini fcntl işlevinde F_SETOWN komutunu kullanarak belirtebilirsiniz; bkz. Sinyallerle Sürülen Girdi. Bantdışı veriyi okuma gereksinimi gibi bir durumda uygun hareketi yapmak için bu sinyalin yakalayıcısını kurmanız gerekir, bkz. Sinyal İşleme.
Diğer bir seçenek olarak, sokette özel durum oluşması için bekleyebilen select işlevini kullanarak bantdışı veri olana kadar bekleyebilir ya da bekleyen bantdışı veri var mı diye bakabilirsiniz. select işlevi hakkında daha fazla bilgi için Girdi ve Çıktının Beklenmesi bölümüne bakınız.
Bantdışı verinin bildirilmesi (SIGURG veya select ile) bantdışı verinin gelmek üzere olduğunu gösterir; veri daha sonra ulaşabilir. Eğer bantdışı veriyi daha gelmeden okumaya çalışırsanız, recv işlevi EWOULDBLOCK hatası ile sonlanır.
Bantdışı veri gönderilince, akımdaki sıradan veri otomatik olarak "im"lenir, ki bu da bant-dışı verinin "ne durumda olabileceğini" gösterir. Bu bantdışı verinin anlamı "şimdiye kadar gönderdiklerimi iptal et" ise kullanışlıdır. Buradaki alıcı işlemde, imlenmeden önce sıradan verinin gönderilip gönderilmediğini sınayabilirsiniz:
success = ioctl (socket, SIOCATMARK, &imgeldi);
Eğer soketin okuma göstericisine "im" ulaştıysa bir tamsayı değişken olan imgeldi sıfır olmayan bir değer yapılır.
Burada bantdışı iminden önce gelen sıradan veriyi iptal eden bir işlev görüyoruz:
int
discard_until_mark (int soket)
{
  while (1)
    {
      /* Bu isteğe bağlı bir sınır değildir; herhangi bir büyüklük olabilir.  */
      char tampon[1024];
      int imgeldi, tamam;

      /* İm geldiyse işlev dönsün.  */
      tamam = ioctl (soket, SIOCATMARK, &imgeldi);
      if (tamam < 0)
        perror ("ioctl");
      if (imgeldi)
        return;

      /* Aksi takdirde, bir miktar sıradan veriyi oku ve iptal et.
         Bu imden sonrasını okumamayı garantiler
         tabii ki imden önce başlıyorsa.  */
      tamam = read (soket, tampon, sizeof(tampon));
      if (tamam < 0)
        perror ("read");
    }
}
Eğer imden önceki veriyi iptal etmek istemiyorsanız, belki de bantdışı veriye sistem içi tampon bölgesinde yer açmak için bir kısmını okumak istersiniz. Eğer bantdışı veriyi okumaya çalışır ve EWOULDBLOCK hatası alırsanız, bir miktar sıradan veriyi okumaya çalışın (kaydederek daha sonra istediğinizde kullanabilirsiniz) ve yer açıldığını görün. Örnek:
struct tampon
{
  char *tmp;
  int boyut;
  struct tampon *sonraki;
};

/* Bantdışı veriyi SOKET'ten oku ve verinin adresini ve
   büyüklüğünü `struct tampon' içinde döndür.

   Bantdışı veriye yer açmak için bir miktar sıradan veriyi okumak gerekebilir.
   Bu durumda, sıradan veri 'sonraki' alanında bulunan
   bir tamponlar zincirine kaydedilir.  */

struct tampon *
read_oob (int soket)
{
  struct tampon *son = 0;
  struct tampon *liste = 0;

  while (1)
    {
      /* Bu keyfi bir sınırdır.
         Bunu sınırsız yapmayı bilen birileri var mı?  */
#define BOYUT 1024
      char *tamp = (char *) xmalloc (BOYUT);
      int tamam;
      int imgeldi;

      /* Bantdışı veriyi bir daha okumaya çalışalım.  */
      tamam = recv (soket, tamp, BOYUT, MSG_OOB);
      if (tamam >= 0)
        {
          /* Artık elimizde, döndürüyoruz.  */
          struct tampon *veri
            = (struct buffer *) xmalloc (sizeof (struct tampon));
          veri->tmp = tamp;
          veri->boyut = tamam;
          veri->sonraki = liste;
          return veri;
        }

      /* Yoksa, imin gelip gelmediğine bakalım.  */
      tamam = ioctl (soket, SIOCATMARK, &imgeldi);
      if (tamam < 0)
        perror ("ioctl");
      if (imgeldi)
        {
          /* İm gelmiş; geriye kalan sıradan verinin faydası olmaz.
             Bir süre bekleyelim.   */
          sleep (1);
          continue;
        }

      /* Aksi takdirde, bir miktar sıradan veriyi okuyup kaydedelim.
         Bu imden sonrasını okumamayı garantiler
         tabii ki imden önce başlıyorsa.  */
      tamam = read (soket, tamp, BOYUT);
      if (tamam < 0)
        perror ("read");

      /* Bu veriyi tampon listesine kaydedelim.  */
      {
        struct tampon *veri
          = (struct tampon *) xmalloc (sizeof (struct tampon));
        veri->tmp = tamp;
        veri->boyut = tamam;

        /* Yeni veriyi listenin sonuna ekleyelim.  */
        if (son)
          son->sonraki = veri;
        else
          liste = veri;

        son = veri;
      }
    }
}
Önceki Üst Ana Başlık Sonraki
Bayt Akımlı Bağlantı Sunucusu Örneği Başlangıç Datagram Soket İşlemleri
Bir Linux Kitaplığı Sayfası