[Çözüldü] C network programlama-IP sorunu

Başlatan sem, 04 Mart 2010 - 23:28:33

« önceki - sonraki »

0 Üyeler ve 2 Ziyaretçi konuyu incelemekte.

sem

Arkadaşlar herkese merhabalar. C ile ilgili çözemediğim bir soru sormak istiyorum.

sunucu - istemci tarzı çok basit ve genel bir program yazdığım zaman; sunucu programına da, istemci programına da IP adresini "127.0.0.1" olarak tanıtırsam sorun yaşamıyorum. Fakat IP adresini normal dinamik IP numaram olarak  yazdığım zaman; sunucu programında bir hata almıyorum, oluşturulan soket dinlenilebiliyor, istemci programında ise connect(); fonksiyonunda hata alıyorum. Aynı programı Windowsa uyarlayıp çalıştırınca gene sorun aynı şekilde devam ediyor. Portların firewall ile güvenlik nedeniyle kapatıldığını düşündüm fakat modem ayarlarından firewall'u kapatınca sorun çözülmedi. Başka yazılmış örnek programları internetten indirip çalıştırdım fakat onlar da aynı şekilde INADDR_ANY kullanılmış ve onlar da IP adresi ile deneyince hata verdi. Ubuntuda portları kullanabilmek için ayrıca bir ayar yapmam gerekir mi,  IP adresini programa nasıl kabul ettirebilirim, sorun sizce neden kaynaklanabilir, öneriniz nedir? Şimdiden teşekkürler...
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

heartsmagic

Açıkçası programlama sorun beni aşıyor, bu nedenle o konuda yorum yapamıyorum. Fakat Ubuntu üzerinde portlar eğer kullanıcı tarafından engellenmiyorsa sorun olmazlar. Fakat sen dinamik ip ile deniyorsan istemci üzerinden ve port yönlendirmesi yapmadıysan modemden sorun bu olabilir mi?
Hayattan çıkarı olmayanların, ölümden de çıkarı olmayacaktır.
Hayatlarıyla yanlış olanların ölümleriyle doğru olmalarına imkân var mıdır?


Böylece yalan, dünyanın düzenine dönüştürülüyor.

sem

     Teşekkürler cevabınız için. Aslında benimde hakim olduğum bir konu değil açıkcası. Fakat istemci üzerinden de sunucu üzerinden de port yönlendirilmesi yapılıyor. Yani sunucuya dinleme için hangi portu veriliyorsa, istemciye de bağlantı için aynı port veriliyor. IP'yi "127.0.0.1" yaparsam her iki programda da bir sorun olmuyor. İki ayrı terminalden, birisinde sunucu birisinde istemciyi çalıştırırarak bağlantıyı sağlayabiliyorum. Ama işte az öncede dediğim gibi IP adresini kendi adresim olarak verince sıkıntı yaşıyorum.
      İki programı aynı bilgisayarda deniyorum onla bir alakası olup olmadığı bile geliyor aklıma. Bilmeyince konuyu; alakalı alakasız her ihtimal geliyor herhalde insanın aklına.
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

heartsmagic

Aynı bilgisayarda denediğinden sorun çıkmaması bana yine port sorunu gibi geliyor. Şimdi, bu bilgisayarda kullanılan port modemden yönlendirilmiş durumda olmasına rağmen bu problem yaşanıyorsa açıkçası konu sistemden ziyade kodlamada olabilir. Dediğim gibi bu mesele de beni aşıyor.

http://www.canyouseeme.org/ adresinden açtığın portun dışarıdan açık olup olmadığını görebilirsin.
Hayattan çıkarı olmayanların, ölümden de çıkarı olmayacaktır.
Hayatlarıyla yanlış olanların ölümleriyle doğru olmalarına imkân var mıdır?


Böylece yalan, dünyanın düzenine dönüştürülüyor.

sem

Sitenin söylediğine göre portum kapalı gözüküyor. Neden olarak da "zaman aşımı" gösteriyor. Ne yapmam gerekir portu kullanabilmem için, bilginiz var mı?
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

sema

#5
Uğraşmışlığım olmamakla birlikte 'port açma ya da kapama' diye aratırsanız sanırım çözüme ulaşırsınız. Modem ayarlarından yapılıyordu da. Hatta ben bir arayayım, ek yaparım bulursam..

Şunlar var:
http://forum.ubuntu-tr.net/index.php/topic,7843.0.html
http://forum.ubuntu-tr.net/index.php?topic=4538.0 (dahası da var).
susema

sem

Alıntı yapılan: semagkyz - 05 Mart 2010 - 02:04:12
Uğraşmışlığım olmamakla birlikte 'port açma ya da kapama' diye aratırsanız sanırım çözüme ulaşırsınız. Modem ayarlarından yapılıyordu da. Hatta ben bir arayayım, ek yaparım bulursam..

Şunlar var:
http://forum.ubuntu-tr.net/index.php/topic,7843.0.html
http://forum.ubuntu-tr.net/index.php?topic=4538.0 (dahası da var).


Gönderdiğiniz linklerden port açma; /* iptables -A INPUT -p tcp -i eth0 --dport 8000 -j ACCEPT  */  komutu ile 8000. port açılıyor. Bu komutu yazınca açılan portu, gene gönderdiğiniz linklerde bahsedilen port tarama sitelerinde göremiyorum. Ya da aynı şekilde heartsmagic' in gönderdiği siteden de gözükmüyor. Gerçi port tarama sitelerindeki açık gözüken protları da denedim. Fakat yine erişim sağlayamadım. Ama her nedense artık connect(); fonksiyonu hemen hata vermiyor. Bir müddet bekledikten sonra hataya dönüyor. Açılan portu, port tarama sitelerinde neden görmediğimi anlayamadım açıkcası. Sanırım gecikme sağlayan sebep için kodlara ve portlara tekrar bakmam gerekecek. Cevabınız için teşekkür ederim.


".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

sema


Hımm.. Söylediğim gibi pek denemişliğim yok açıkçası portlarla ilgili mevzuları. Bir de Google'ı deneyin isterseniz. Belki eksik verdiğimiz/yaptığımız bir şeyler vardır. Google baktım da oldukça zengin gözüküyor, portlarla ilgili..
susema

sem

Sanırım son haliyle portlarla ilgili değil, IP adresi ile bir sıkıntım var. Çünkü aynı port ile farklı IP adreslerinde sıkıntı çekiyorum. Adresi değiştirince bind(); hata veriyor.  IP adresini yapılara sokabilmek için bir kaç fonksiyon kullanılabiliyor. Benim denediğim inet_addr(); fonksiyonu. Daha taşınabilir olduğu için onu deniyorum, belki de diğer yöntemler ile daha verimli olur. Ben öğrenebildiğim bütün yöntemleri deneyip, sorunlu kodu gönderirsem daha çabuk sonuca ulaşacağım sanırım...
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

sema

Bir de mesela ben bütün fonksiyonları hatta çoğu fonksiyonu Ubuntu altında çalıştıramadığımı söyleyeyim, belki çözümü vardır ama çok irdelemediğimi de ekleyeyim de yine de sanırım Win ortmında da aynı hata ile karşılaşıyorsun?! Eğer denemediysen Win'de de dener misin port açmayı?

Çözüme kavuşursan, bize de anlatır mısın, merak ettim :) Kolay gelsin.
susema

sem

Bazı komutlar evet çalışmıyor linux altında ama benim kullandıklarım standart C fonksiyonu. Sadece başlık dosyaları değişiyor aslında komutlar aynı hatta windowsta çalışabilmesi için ek komutlar yazmam gerekiyor. Yani ubuntuda daha rahat çalışabilmem lazım aslında ama benim bilgi eksikliğimden kaynaklı bir durum =). Şu an Kocaeli'deyim, öğrenci evinde. Akşama İstanbula gidip programları aynı  ağdaki iki bilgisayarda deneyeceğim. Olmazsa dediğiniz gibi windows ortamında deneyeceğim, o da olmazsa daha önce dediğim gibi kullandığım fonksiyonları değiştireceğim. O da olmazsa tekrar soracağım artık çünkü çok zamanımı aldı bu iş. Biri dese ki öyle olmaz böyle böyle yapacaksın daha ilerleyeceğim ama tıkandım burda =). Farklı fonksiyonlar kullanara bind(); fonksiyonunda hatanın portla mı IP ile mi ilgili olduğu anlaşılır diye düşünüyorum ama emin değilim. Hafta sonuna kadar diğer fonksiyonları da interntten arayıp denerim artık. Teşekkür ederim @semagkyz; verdiğinz bilgiler için...
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

rutku

Yazdığınız kodu gönderebilir misiniz ? Sunucu ve istemciyi yollayın. Burdaki bağlantı faydalı http://ileriseviye.org/arasayfa.php?inode=html_tr/index.html
Hayallerini kodla ...

uKiriş
Mezgeldek

sem

Alıntı yapılan: Racih - 06 Mart 2010 - 17:12:42
Yazdığınız kodu gönderebilir misiniz ? Sunucu ve istemciyi yollayın. Burdaki bağlantı faydalı http://ileriseviye.org/arasayfa.php?inode=html_tr/index.html

Evet gönderdiğinz linki incelemiştim önceden, hatta ordan öğrendim diyebilirim daha doğrusu ordan öğrenememişim. Siz ordaki bilgilerle yapabildiyseniz ben birşeyleri gözden kaçırdım demek ki.Kodu gönderiyorum, sunucunun kodunu gönderiyorum. Sanırım bunu hallettikten sonra istemci daha kolay gibi o nedenle öncelikli olarak sunucuyu göderiyorum. Sorun şu ki aşağıdaki kodda IP adresi 127.0.0.1 olarak girilince program çalışıyor. Çalışıyordan kastım soket bind edilip, dinlemeye geçilebiliyor. Ama IP yi; IP gösteren internet sitelerinden bakıp gözüken IP adresimi yazınca soket bind edilemiyor. Aslında mantıklı gelmiyor da değil bind edilmemesi, bir takım ek şeylerin yapılması gerektiği kesin. Yoksa oraya herhandi bir kişinin IP adresini yazdığım zaman, mantıken programın o IP adresindeki istenilen portu dinlemesi gerekiyormuş gibi geliyor. Git gide karışıyor ama insanın kafası bir sürü soru işareti oluştu kafamda. Bilen birisini bulursam soracağım birkaç şey daha oldu kafamda...

NOT: Aşağıdaki kodda veri alış verişi döngüye sokulmamış, ya da başka eksik şeyler görebilirsiniz. Tek amaç bağlantı kurabilmek...


#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define PORT_NO         5010
#define SOCKET          int
#define SOCKET_ERROR    -1
#define INVALID_SOCKET  -1
#define listen_sirasi     2

int main()
{
   SOCKET dinleme, transfer;
   struct sockaddr_in serverbilgileri, clientbilgileri;
   int clientbilgileriboyutu;
   char gelenveri[10];

   serverbilgileri.sin_family = AF_INET;
   serverbilgileri.sin_port   = htons(PORT_NO);
   serverbilgileri.sin_addr.s_addr = inet_addr("127.0.0.1");
   
   if(serverbilgileri.sin_addr.s_addr == -1)
   {
      fprintf(stdout,"inet_addr fonksiyonu basarisiz\n");
      perror("inet_addr");
      inet_aton("127.0.0.1",&(serverbilgileri.sin_addr));

         if(&(serverbilgileri.sin_addr) == 0)
         {
            fprintf(stdout,"inet_aton fonksiyonu da basarisiz\n");
            perror("inet_aton");
            return-1;
         }
         else
         {
            fprintf(stdout,"inet_aton fonksiyonu basarili\n");
         }
 
   }
   else
   {
      fprintf(stdout,"inet_addr fonksiyonu basarili\n");
   }

   if((dinleme = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == INVALID_SOCKET)
   {
      fprintf(stdout,"dinleme soketi olusturulamadi\n");
      perror("socket");
      return -1;
   }
   else
   {
      fprintf(stdout,"dinleme soketi olusturuldu\n");
   }
   
   if(( bind(dinleme,(struct sockaddr *)&serverbilgileri,sizeof(struct sockaddr))) == SOCKET_ERROR)
   {
      fprintf(stdout,"dinleme soketi bind edilemedi\n");
      perror("bind");
      shutdown(dinleme,2);
      return -1;
   }
   else
   {
      fprintf(stdout,"dinleme soketi bind edildi\n");
   }
 
   if((listen(dinleme,listen_sirasi)) == SOCKET_ERROR)
   {
      fprintf(stdout,"soket dinlenemiyor\n");
      perror("listen");
      shutdown(dinleme,2);
      return -1;
   }
   else
   {
      fprintf(stdout,"soket dinlemede\n");
   }
 
   transfer = accept(dinleme,(struct sockaddr *)&clientbilgileri,&clientbilgileriboyutu);
 
  recv(transfer,gelenveri,10,0);
 
  printf("gelen veri:%s\n",gelenveri);

  shutdown(dinleme,2);
  shutdown(transfer,2);

return 0;
}

".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

sem

#13
Biraz açayım o zaman sorumu belki yanıtlanabilir bu şekilde.

   serverbilgileri.sin_family = AF_INET;
   serverbilgileri.sin_port   = htons(PORT_NO);
   serverbilgileri.sin_addr.s_addr = inet_addr("127.0.0.1"); --->>>IP

satırları ile struct sockaddr_in yapısına server' ın bilgilerini tanıtıyorum. AF_INET denilen TCP protokolü için girilmesi gereken değer. port numarasını define ile 5010 olarak bildirmişim. IP ise malum IP; konuyu açmama neden olan IP. Şimdi diyelim ki program kendi IP adresim ile çalışacak olsa; evden 4 5 bilgisayar ile giriliyor nete ve hepsinin IP numarası aynı. Açılan portun modemle alakası varsa (ki portlar her bilgisayar başına, kendine ait 65536 adet bulunuyormış, network programlama ile ilgili her dökümanda anlatılıyor.), aynı IP adresinden girilen hangi bilgisayar için, hepsi için mi açılıyor. Ya da denildiği gibi bilgisayara özgü olduğundan dolayı sadece server programının kurulu olduğu bilgisayar için açılıyorsa; o zaman client bilgileri aynı IP adresinden giren örneğin 5 bilgisayar arasından benim bilgisayarımı nasıl bulacak?


EKLEME:
    Az önce sorduğum sorulardan sonra, cevapları ararken internetim çok kastı. Wireless'ten birileri mi giriyor diye bakarken sadece kendimi gördüm ve bilgisayar adının yanında 192.168.1.64 yazıyordu. Ordan yola çıkarak; 192.168.1.1 arayüzündeki port açma menüsünden; 192.168.1.64 için 16000 numaralı portu açmayı denedim. Sonra da heartsmagic'in gönderdiği siteden kontrol ettim. Daha önceden denediğim bütün portlarda "Connection time out" hatası ile portun açık olmadığı iletisini alıyordum. Bu şekilde deneyince "Connection refused" hatası aldım. Bu hatanın da ilgili portu dinleyen bir program olmadığı zaman alınan bir hata olduğunu okumuştum. Server programında struct sockaddr_in yapısına IP yerleştirmeyi;

serverbilgileri.sin_addr.s_addr = INAADR_ANY;

olarak değiştirip, programı çalıştırdıktan sonra siteden portu kontrol edince açık olduğu gördüm.

SONUÇ: server programındaki kod ile açmaya çalıştığımız port tabi ki kendi bilgisayarımızın portuymuş. Bu denemeler sırasında server programının internete açmış olabildim. heartsmagic'in gönderdiği site sayesinde onu da öğrenmiş oldum. Yani server programına IP yerleştirilebiliyor artık... Bir nebze de olsa da ilerleme kaydedebildim...

SORUN:  Client programını çalıştırınca "Connection refused" hatası aldım bu sefer =). Sanırım bu gene yukarda sorduğum soru ile alakalı: "Bir IP adresinden 5 bilgisayar bağlanıyorsa ve server programı bu 5 bilgisayar arasından birinde yürütülüyorsa, client programına bu IP adresi yazıldığında, client programı; 5 bilgisayar arasından server programının hangisinde çalıştığı nerden biliyor?"
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

heartsmagic

Son sorunu anlayamadım. Biraz da konuya vakıf olmadığımdan olabilir. Fakat sunucu bilgisayarın üzerinde bir program dışarıya servis sağıyorsa ve bunu bir port aracılığıyla yapıyorsa, bu port da modem (ya da router) üzerinden sunucu bilgisayara yönlendirilmişse, dışarıdan (istemci-client?) gelen her istek bu port üzerinden yapılacağından dolayı doğrudan sunucu bilgisayara aktarılır.
Hayattan çıkarı olmayanların, ölümden de çıkarı olmayacaktır.
Hayatlarıyla yanlış olanların ölümleriyle doğru olmalarına imkân var mıdır?


Böylece yalan, dünyanın düzenine dönüştürülüyor.

sem

server = sunucu;
client  = istemci;  // Bu ikisi yabancı kelimeden daha ziyade terim gibi kullandığı için çok dikkat etmedim Türkçe olup olmadığına, genelde her yerde server-client mimarisi olarak geçiyor.

   @heartsmagic tam olarak demek istediğim şuydu; dediğiniz gibi o port üzerinden gelen istek sunucu bilgisayara yönlendiriliyor. Kafamda şöyle bir konuda bir soru işareti oluşmuştu; mesela server progamı 5000. port üzerinden işlem yapacak olsun, modem üzerinden 5000. portu açınca, aynı IP ile giren başka bilgisayarda da 5000. port kullanılıyorsa, istemci hangi 5000. porta yönlendirilecek?  Biz  routerle bağlanıyoruz ve ben routerde 192.168.1.64 olarak gözüküyorum ve kendim için yani 192.168.1.64 bilgisayarı için 5000. portu açıyorum router ayarlarından. Ama diyelim aynı programı, yani aynı sunucu programını, aynı ağdaki 192.168.1.65 bilgisayarına da kurup ikisini de çalıştırırsak, istemci hangi sunucu programına yönlendirilecek? 192.168.1.64 mü 192.168.1.65 mi? Aynı program için bir önemi olmayabilir belki bu sorrmun ama 192.168.1.64 ve 192.168.1.65 bilgisayarlardında 5000. portu kullananan farklı iki program yürütüldüğü zaman, portlarda bir karışıklık olma ihtimali nedir?

   Bu soru artık merak giderme amaçlı olmuştur. An itibari ile sorunumu çözmüş bulunuyorum. heartsmagic , sizin gönderdiğiniz sitenin yardımı büyük olmuştur ve site sayesinde  portlarla ilgili ufkum biraz daha genişledi diyebilirim . Hiç bilmiyordum biraz öğrenmiş oldum diyeyim. Teşekkür ederim yardımlarınız için...
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

heartsmagic

 Sanırım router üzerinden aynı portu farklı IP adreslerine yönlendiremiyoruz. Fakat senin istediğin tarzda bir uygulama da örneklerine karşılaşabileceğimiz türden bir mesele. Sanırım farklı çözüm yolları vardır, ancan konu beni aşıyor ne yazık ki :) Sorunun çözmene sevindim, konu şimdilik açık kalsın. Ağ ve programcılık üzerine bilgi sahibi arkadaşlar son sorun hakkında belki yorum yaparlar.
Hayattan çıkarı olmayanların, ölümden de çıkarı olmayacaktır.
Hayatlarıyla yanlış olanların ölümleriyle doğru olmalarına imkân var mıdır?


Böylece yalan, dünyanın düzenine dönüştürülüyor.

sem

Aslında sanınız mantıklı geliyor. ("Sanırım router üzerinden aynı portu farklı IP adreslerine yönlendiremiyoruz"). Çünkü örneğin bir port tarama programı yazdığımızda açık olan portu iki kere göstermesi gerekecek, çözümü olabilir belki ama mantıklı gelmiyor ilk bakışta. Ev arkadaşları gelsin deneyeceğim hemen çok merak ettim. Sorun neydi nasıl çözüldü onu da toparlarım yazarım ki aynı hataya düşenler benim gibi bilgi eksikliğinden dolayı 1.5 ay uğraşmasınlar, yazdıkları çalışan program için port yüzünden bütün kaynakları okumasınlar...
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

heartsmagic

Güzel olur @sem0900, arkanda güzel bir referans bırakmış olursun. Şöyle biraz daha bakındım da etrafta da aynı şey söyleniyor. Tek port, tek IP adresi.
Hayattan çıkarı olmayanların, ölümden de çıkarı olmayacaktır.
Hayatlarıyla yanlış olanların ölümleriyle doğru olmalarına imkân var mıdır?


Böylece yalan, dünyanın düzenine dönüştürülüyor.

sem

Sorunun ve çözümün iyi anlaşılması için toparlayarak gönderiyorum herşeyi:


#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>

#define PORT_NO  16004


#define BOTH               2
#define SOCKET            int
#define INVALID_SOCKET    -1
#define SOCKET_ERROR      -1
#define listen_kuyrugu     1


int main()
{
    SOCKET dinleme_soketi, transfer_soketi;
    struct sockaddr_in   sunucubilgileri,istemcibilgileri;
    int boyut,gelenveri_boyutu,gidenveri_boyutu;
    char gelenveri[20], gidenveri[20];

   
    sunucubilgileri.sin_family         = AF_INET;
    sunucubilgileri.sin_port           = htons(PORT_NO);   
    sunucubilgileri.sin_addr.s_addr  = INADDR_ANY;



    if((dinleme_soketi = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
    {
       printf("dinlenilecek soket olusturulamadi...\n");
       perror("socket");
       return -1;
    }

    if((bind(dinleme_soketi,(struct sockaddr *)&sunucubilgileri, sizeof(struct sockaddr))) == SOCKET_ERROR)
    {
       printf("dinleme soketi bind edilemedi...\n");
       perror("bind");
       return -1;
    }

    if((listen(dinleme_soketi,listen_kuyrugu)) == SOCKET_ERROR)
    {
       printf("bind edilen dinleme soketi, dinlemeye gecemiyor...\n");
       perror("listen");
       return -1;
    }

    if((transfer_soketi = accept(dinleme_soketi, (struct sockaddr *)&istemcibilgileri, &boyut)) == INVALID_SOCKET)
    {
       printf("Dinlenen sokete gelen istek kabul edilemiyor...\n");
       perror("accept");
       shutdown(dinleme_soketi, BOTH);
       return -1;
    }

    printf("Istemcinin veri gondermesi bekleniyor\n");

    recv(transfer_soketi, gelenveri, gelenveri_boyutu,0);
    printf("gelenveri:%s\n",gelenveri);

    printf("Gonderilecek Bilgi:");
    scanf("%s",gidenveri);


    gidenveri_boyutu = strlen(gidenveri);
    send(transfer_soketi,gidenveri,gidenveri_boyutu,0);
   
shutdown(dinleme_soketi,BOTH);
shutdown(transfer_soketi,BOTH);

   
   
}


 

Genel olarak anlatımı; sunucu programının temel olarak algoritması:

socket oluştur                          -->>socket();
soketi bağdaştır                      -->>bind();    //hangi ağ kartı ve hangi portun dinleneceği bildirilir.
soketi dinle                               -->>listen(); 
sokete istek olursa kabul et -->>accept();  //geri dönüşü bir soket handle alanıdır.
                                                                           Çünkü dinlenen ve bilgi alış verişi olan soketler
                                                                           farklıdır.

veri alma ve gonderme         -->>send();
                                                         accept();
görevi biten soketleri kapat -->>close();
                                                         shutdown();       


   Benim sorunum yukarda da en önemli olarak duran bind(); fonksiyonu ile ilgiliydi. bind(); fonksiyonu;

   int bind(int socket, struct sockaddr * dinlemesoketibilgileri,int boyut);

   Bu parametrelerden ikincisi içine; dinleyeceğimiz port,handi adres ailesinin kullanılacağı, hangi IP üzerinde dinlemeye yapılacağı yerleştirilmektedir. Buradaki struct sockaddr genel bir yapıdır ve birçok adres bilgsini barındırabilir.
   
   struct sockaddr{
   unsigned short sa_family;  //adres ailesi
   char sa_data [14];         //protokol adresinin 14 baytı
                  }

   Daha sonraları bu yapının karmaşıklığı nedeniyle her protokol için yeni yapılar geliştirilmiş. TCP/IP için kullanılan yapı ise struct sockaddr_in yapısıdır. Benim IP yerleştirme sorunum da bu yapıyı doldururken çıkıyordu.

   struct sockadd_in
   {
      short int sin_family;           //adres ailesi
      unsigned short int sin_port;    //port numarası
      struct in_addr sin_addr;        //IP numarasını gireceğimiz yapı
      unsigned char sin_zero;         //yapının boyunu strcut sockaddr yapısına eşitlemek için
   }   

   Burda sockaddr_in yapısının IP'yi alacak olan elemanı sin_addr de struct in_addr yapısında tanıtılmıştır.

  struct in_addr {
    union {
       struct {UCHAR s_b1, s_b2, s_b3, s_b4} S_un_b;
       struct {USHORT s_w1, s_w2} S_un_w;
       ULONG s_addr;
                 }S_un;
         };
   Yapının S_un elemanı bir birliktir ve birliğin s_addr elemanı IP adresini long olarak almaktadır. IP'yi long türünde girmek kullanışlı olmadığı yani genel olarak noktalı yapıda tutulduğu için [127.0.0.1 (localhost)]  htonl(host to network long) fonksiyonu yerine inet_addr()  fonksiyonu kullanılır. Bu fonksiyon noktalı biçimde aldığı IP adresini long türüne döndürür. inet_addr() fonksiyonu IP yi zaten ağ byte sırasına göre dizdiği için htonl() fonksiyonunu çağırmamıza gerek olmuyor.

anektod:#define s_addr S_un.s_addr -->>makrosu tanımlı olduğu için s_addr elemanına daha kolay ulaşabiliyoruz.

   Özetle IP'yi yerleştirdiğimiz satırı;

   sunucubilgileri.sin_addr.s_addr = inet_addr("127.0.0.1");
   
   olarak yazınca ki genel olarak bütün örneklerde bu şekilde tanıtılmış; program hatasız çalışıyor, istemciye yanıt da veriyor fakat sadece kendi bilgisayarım içinde  yanıt veriyordu. Yani program sadece kendi bilgisayarımda çalışıyordu. Zaten 127.0.0.1 de , makinanın kendisini temsil etmesi için gereken localhost numarasıymış. Bunu öğrendikten sonra programı http://www.ip-numaram.com/ adresinden aldığım IP numaram ile denemeye başladım. Bu şekilde çalıştıramadım programı.Aldığım hata ise bind(); fonksiyonundan kaynaklanıyordu. bind(); fonksiyonu hata verince yerleştirdiğim portla ilgili sıkıntı olabileceğini düşündüm ve heartsmagic'in gönderdiği: http://www.canyouseeme.org/ adresinden kullanmak istediğim portun açık olmadığını öğrendim. Zaten bu şekilde; port açık değilken program derleme hatası vermese bile çalışma sırasında port nedeniyle hata verecekti, kaldı ki IP kısmına kendi dinamik IP adresimi yazınca program derlenmiyordu bile. Sorun nasıl çözüldü?

1.) Kullandığım router'ın benim bilgisayarıma atadığı IP adresi için (192.168.1.64) programda kullanmak istediğim portu açtım. Yani bir port sorunu olduğu doğruydu. Bu şekilde açtığım portu gene heartsmagic'in gönderdiği sitede denedim. Gene kapalı gözüktü ama diğer denemelerime göre farklı bir hata ile kapalı olduğunu söyledi. Hataya göre program çalışsa aslında port açık gibi değerlendirilecek. Yani port sorunu kalktı. //Yani kullanacağınız portu kendi bilgisayarınız için, router'dan da açmanız gerekiyor!

2.) Programın IP girme satırını şu şekilde değiştirdim;

  sunucubilgileri.sin_addr.s_addr = INADDR_ANY;

  Burdaki INADDR_ANY sabiti aslında 0 değerine tekabul ediyor. Anlamı ise; "hosta bağlı tüm network kartlarını değerlendir", yani benim bilgisayarım için "kendi IP'mi otomatik olarak al". Satırı bu şekilde değiştirip, programda belirttiğim portu routerdan açınca, program çalışmaya başladı.

  Yani aslında sorun tamamen portun routerdan açılmamış olmasıymış. Programı çalışır hale getirebildim ama hala kafamda soru işaretleri var. Örneğin hala; inet_addr(); fonksiyonu içinde dinamik IP numaramı yazınca program çalışmıyor. "istenilen adres atanamadı" şeklinde hata alıyorum. Bunun nedenini bilen varsa, paylaştığında çok bahtiyar eder beni=). Neden çalışmıyor olabilir en azından fikrini söylerse ordan yola çıkarak bir yere varabilirim belki.

NOT: Tabi ki network programlama için kullanılan fonksiyonlar bu kadar değil. Hatta yukardaki örnek de çok başarısız bir örnektir. Nedeni ise bir iki kere  yazışırsınız ancak o işe yarar o program. Çünkü bir amaca yönelik değil, sadece bağlantı kurup kuramadığımı denemek için yazdım.  Denemek, işleyişi görmek isteyen olursa kendi IP adresini yazarak aşağıdaki program ile deneyebilir.  Daha fazla bilgi edinmek isteyenler için söylüyorum daha önceden racih'in gönderdiği siteye bakarsanız çok faydalı olacaktır. Benim çalıştığım yer de o site ve ayrıca Kaan Aslan'ın notlarından bakmıştım. Yani bu dediğim iki şeyi kaynak olarak da göstersem daha iyi olur hatta. Tamamen oralardan öğrendiklerimi yazdım. Host adı ile çalışmak, honts(); htonl(); fonksiyonları, ağ byte dizilimi gibi geçen konuların hepsini bu kaynaklardan okuyabilirsiniz. Ayrıca bunları benim gibi biraz araştırmış ve bilgi sahibi olanları düşünerek yazdım, yani ilk defa bakanlar için anlaşılmaz olabilir ama bendeki kaynakları da fotokopi şeklinde olmasa da öğrendiğim şekilde, en baştan ,isteyene yazıp  gönderebilirim. Hatam varsa da düzeltirseniz sevinirim. İyi günler ...

istemci kodu

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>


#define PORT_NO         16004

#define BOTH            2
#define SOCKET          int
#define SOCKET_ERROR   -1
#define INVALID_SOCKET  -1


int main()
{
   SOCKET sunucuya_baglan;
   struct sockaddr_in sunucubilgileri;
   char gelenveri[20],gidenveri[20];
   int gelenveriboyutu,gidenveriboyutu;

   sunucubilgileri.sin_family      = AF_INET;
   sunucubilgileri.sin_port        = htons(PORT_NO);
   sunucubilgileri.sin_addr.s_addr = inet_addr("78.174.252.85");

   if((sunucuya_baglan = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
   {
      printf("suncuya baglanmak icin soket olusturulamadi...\n");
      perror("socket");
      return -1;
   }

   if((connect(sunucuya_baglan,(struct sockaddr *)&sunucubilgileri, sizeof(struct sockaddr))) == SOCKET_ERROR)
   {
      printf("sunucuya baglanilamadi...\n");     
      perror("connect");
      return -1;
   }
   else
   {
      printf("Sunucuyla baglanti kuruldu...\n");
   }

   printf("Gonderilecek veri:");
   scanf("%s",gidenveri);

   gidenveriboyutu = strlen(gidenveri);
   send(sunucuya_baglan,gidenveri,gidenveriboyutu,0);

   printf("Karsi tarafin veri gondermesi bekleniyor:\n");
   recv(sunucuya_baglan,gelenveri,gelenveriboyutu,0);

   printf("gelenveri:%s\n",gelenveri);

   shutdown(sunucuya_baglan,BOTH);
}






/*@heartsmagic evdeki router ile aynı port numarasını iki bilgisayar için açmayı denedim. Evde iki bilgisayar vardı. Routerda birisi 192.168.1.64 diğeri 192.168.1.65 olarak gözüküyor. İkisi için de 16005 numaralı portu açmayı denedim. Herhangi bir hata vermesi gerekiyor muydu bilmiyorum fakat hiçbir şekilde bir hata veya uyarı mesajı vermedi. O zaman daha önceki sorumdan yola çıkarak yukardaki sunucu programını (arkadaş için windowsa uyarlamak zorunda kaldım) iki bilgisayarda da çalıştırdım. Başka bir arkadaşa da yine windowsa uyarlayarak istemci programını gönderdim. Yani aynı IP adresinde aynı portu dinleyen iki program açtık. Programlar hata vermedi. "adres zaten kullanılıyor " gibi falan herhangi bir hata almadık. İkimizin bilgisayarı da portu dinlemeye geçti. Fakat uzaktan bağlanan arkadaş, bana değil diğer bilgisayara bağlandı. Onlar birbirine bağlandı benim ki hala port dinleniyor diyordu. Artık neye göre iki sistem de windows o bir kıstas mıdır? Ya da arkadaş için daha sonra açtık 16005. portu, günclliğe göre mi yönlendirme yapıldı bilmiyorum ama hata almadık sadece istemci diğer arkadaşa yönlendirildi. Linux dışlandı mı artık ne olduysa! =)=)*/



".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

heartsmagic

Öncelikle açıklaman için teşekkürler, fazlaca emek vermişsin.
Port yönlendirmesi Windows için değil de muhtemelen modemin kendine göre belirlediği bir önceliğe göre olmuştur. Yarın aynı şeyi denediğinde bakarsın Linux kurulu makineye kıyak geçer :)

Cümlelerin arasında sorduğun soruyu biraz irdelemek istiyorum. Sen şimdi programa dış IP adresini (dinamik derken bunu kast ettin sanırım?) yazdığında kendin içeriden mi denedin programı? Dışarıdan birisine denetme imkânın oldu mu?
Hayattan çıkarı olmayanların, ölümden de çıkarı olmayacaktır.
Hayatlarıyla yanlış olanların ölümleriyle doğru olmalarına imkân var mıdır?


Böylece yalan, dünyanın düzenine dönüştürülüyor.

sem

Aslında gösterdiğiniz ilgi için ben teşekkür ederim.
    Dinamik IP derken aynen dediğiniz gibi dış IP'yi kasdediyorum. Sorunuzu doğru anladıysam, "dış IP'yi girdikten sonra programın çalışır halini, dışardan birisine denettin mi?" olarak anladım. Eğer bunu sorduysanız evet, dışardan arkadaşlara denettim , programın son hali ile dışardan birisi ile bağlantı kurulabiliyor,  yok öyle değil de ben yanlış anladıysam, "Dinamik IP'yi girince çalışmayan programın, çalışıp  çalışmadığına karar vermek için sadece kendi bilgisayarında mı denedin, yoksa dışardan birilerine denettin mi?" olarak sorduysanız; dış IP'yi girdiğim zaman, aslında derlenmiyor program. O nedenle dışardan birisine denetme imkanı bulamadım. Dış IP'yi tanıtma şeklim önceden tanımlanmış INADDR_ANY, sabiti ile mümkün oldu. Yoksa noktalı formatta örneğin " 129.43.54.124" gibi bir IP'yi gerekli yere(inet_addr fonksiyonuna) yerleştiremedim.

  Ya da bunların ikisini de sormak istemediyseniz soruyu baştan alabilir miyim ?
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

heartsmagic

Tamam, ben derleme işlemini es geçmişim. Sen sabit bir şekilde yapınca oldu yani. Artık konu beni aşıyor sanırım :) Bu noktadan sonra hem ağ hem C üzerinde yorum yapabilecek birileri gerekecek :)
Hayattan çıkarı olmayanların, ölümden de çıkarı olmayacaktır.
Hayatlarıyla yanlış olanların ölümleriyle doğru olmalarına imkân var mıdır?


Böylece yalan, dünyanın düzenine dönüştürülüyor.

sem

Evet sanırım dediğiniz gibi birileri gerekecek. Çok teşekkür ederim yardımlarınız için, özellikle heartsmagic size ayrıca da teşekkür ederim, kilit noktası olan port krizini gönderdiğiniz site sayesinde çözdüm gerçekten. Umarım bilirkişiler konuyu görürler de kalan soru işaretlerini giderirler. Ya da konu kapanır mı artık bilemiyorum, artık ne çıkarsa bahtıma =). ve iyi geceler...
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

heartsmagic

Rica ederiz @sem0900, umarım diğer problemini de halledersin. Konu şimdilik açık kalsın, yorum yapacak birileri gelirse tavsiyelerini bırakırlar başlığa.
Hayattan çıkarı olmayanların, ölümden de çıkarı olmayacaktır.
Hayatlarıyla yanlış olanların ölümleriyle doğru olmalarına imkân var mıdır?


Böylece yalan, dünyanın düzenine dönüştürülüyor.