Jump to content
Forumu Destekleyenlere Katılın ×
Paticik Forumları
2000 lerden beri faal olan, çok şukela bir paylaşım platformuyuz. Hoşgeldiniz.

C'de struct gönderme ve alma


Artariel

Öne çıkan mesajlar

acayip bir problem çıktı karşıma. tcp üzerinden aşağıdaki structu gönderiyorum send() ile ancak recv() ile bu pakedi alınca char okunuyor, int kısmı gelmiyor. yada öyle bir şey. o intli kısmı kullanınca program hata raporu veriyor, debuggerde açıp recv() ile gelen int'in değerine bakıyorum : -8562526 gibi negatif bir değer gösteriyor.

Oysaki :
typedef struct asd
{
char a;
int b;
}ASD;

ASD *as=new ASD;
as->a='1';
as->b=5;
send(sock,(char*)as,sizeof(ASD),0);


bu kodun normal çalışması gerekmiyor mu ? neden int değerini alamıyorum ? bir el atın
Link to comment
Sosyal ağlarda paylaş

new ile malloc arasında fark yok sanıyordum. ayrıca char kısmını yolluyor, hatta başka bir tane daha paket yaptım wchar_t asd[50]; içeren, adam adını soyadını yazıp bile yollayabildi, intte floatta falan oluyor bu durum. neyse birazdan malloc deniyecem
Link to comment
Sosyal ağlarda paylaş

new ile malloc arasında dağlar kadar fark var ama bu örnek için fark yaratır mi tam emin değilim. Zira bildiğim kadarıyla bi C++ compilerı için structin tüm alanları default olarak public olan bi classtan farkı yok. Dolayısı ile bi structi newlediğin zaman constructorunu çağırmaya çalışacaktır, eğer amacınız Ansi C structi yazmaksa malloc ile alın yerini bellekten.
Link to comment
Sosyal ağlarda paylaş

her pakette char id; diye paketin idsini tanımamı sağlayan bir değer var.


said:

if (recv(((ARG*)arg)->sock,(char*)&paketid,1,MSG_PEEK) == SOCKET_ERROR)
{

}
else
{
if (paketid == '2')
{
EnterCriticalSection(&sv->join_section);
int a;
//sv->packets[((ARG*)arg)->id]->paket2
a=recv(((ARG*)arg)->sock,(char*)sv->packets[((ARG*)arg)->id]->paket2,5,0);


said:
typedef struct joingame
{
char id;
int gameid;

}MSJ2;
Link to comment
Sosyal ağlarda paylaş

sadece int değil işte. her türlü veri tipi var, bu sadece başlangıç verisini içeriyor, onun dışında float, int, wchar gibi tipleri içerenler de var. oysaki hiçbir şey yapmasam bile olması gerekiyordu yav. sonuçta C'de her byte'a char diyoruz, int 4 bayt ediyor, ben bufferı charlar halinde yüklediğimde 4 lü(int) 1'li (char) bloklar halinde okuyabilmem gerekiyordu. hani eksik byte gönderiliyor dese anlayacam da debuga aldığımda recv komutu 5 byte döndürüyor (char+int) yani orda bir problem yok. ama paket2->gameid değerine baktığımda -8456452 gibi negatif bir rakamı gösteriyor. neyse bu arada mallocu denemedim denediğimde tekrar yazarım.

edit: bi ara tekrar bakarım acaba msg_peek'de unuttuğum bir buffer mı var diye, gerçi her msg_peek'ten sonra temizleyici bir tane daha recv fonk. çağırıyorum
Link to comment
Sosyal ağlarda paylaş

Arakdaşlar fazladan başlık açmak istemiyorum. Siz yazılımcılara sorayım. Yazılım öğrenmek için ezber önemli midir? Yoksa amaç pratikte olayın mantığını mı anlamak. 1 haftaya kursa başlayacam eğer ezber çok önemliyse bir daha düşüneyim. Çünkü berbatım ezber konusunda.

Kusura bakmayın konuyla alakasız da, arkadaşın sorunu nu çözerken banada arada cevap verirseniz sevinirim.
Link to comment
Sosyal ağlarda paylaş

Yani kodun tamamını göremediğim için çok da bi şey söyleyemiyorum aslında, üstelik asıl kodunda da orada yazdığındaki gibi sizeof yerine 5 yazmış mısın bilemiyorum.

Ama sizeof() kullanımı şart. Çünkü bi char bi int alan içeren her struct'ın 5 byte olacağını garanti edemezsin. Derleme esnasında structlar incelenirken, boyutları içlerindeki en geniş veri alanına göre düzenlenir ve ufak olanlar pad edilir. Örneğin o ASD struct'ı aslında 8 byte tutar, en büyük alan int olduğu için 1 byte'lık char'ı da ona göre pad eder. Ya da mesela:

typedef struct _asd {
char a; // 1
// 3 padding
int b; // 4
char c; // 1
// 3 padding
} asd;


Bu struct 12 byte'tır. Ama aşağıdaki gibi tanımlarsan 8 byte:

typedef struct _asd {
char a; // 1
char c; // 1
// 2 padding
int b; // 4
} asd;

Bu da 8 byte mesela:

typedef struct _asd {
char a; // 1
char c; // 1
short d; // 2
int b; // 4
} asd;


Bu tarz belirsizlikleri önlemek için, her zaman boyutu ufak olan verileri önce, büyük olanları sonra yazmak ve sizeof kullanmak şart.
http://en.wikipedia.org/wiki/Data_structure_alignment#Typical_alignment_of_C_structs_on_x86


@Buddha: Ezberden ziyade analitik düşünebilme önemli. Ezber de lazımdır muhtemelen ama programlama unsurlarının biçoğu zamanla pratikleşebilcek şeyler zaten. Mesela bu anlattığım şeye uymak için ilk başta hangi veri tipinin kaç byte tuttuğunu ezberlemen gerekebilir, ama zamanla yer eder. Ya da en kötü ihtimalle hangi tip hangi tipten daha fazla yer tutar onu bilirsin.
Link to comment
Sosyal ağlarda paylaş

oha şimdi ağlayacam sorunu çözdüm (WSAStartup(MAKEWORD(2,0),&wsa) != 0) idi, (WSAStartup(MAKEWORD(2,2),&wsa) != 0) yaptım ve bütün veri doğru dürüst gidiyor. winsock 2.0'la mı alakalıydı şimdi hepsi ? böyle bir saçmalık duymadım. neyse düzeldi.

edit : bu arada bir sorum daha var, bir pointer dizisi tanımladım Players *players[50]; diyerekten. hepsini başlangıçta init ettirmeye gerek yok, pointeri bir yeri göstermeden ve programa hata raporu verdirtmeden nasıl check ederim ? if (players[1]) diyorum mesela ama players[1] tanımlanmadığı için hata raporu alıyorum. işte bu hata raporunu almadan bu pointer var mı yok mu nasıl kontrol ederim?
Link to comment
Sosyal ağlarda paylaş

Artariel said:

edit : bu arada bir sorum daha var, bir pointer dizisi tanımladım Players *players[50]; diyerekten. hepsini başlangıçta init ettirmeye gerek yok, pointeri bir yeri göstermeden ve programa hata raporu verdirtmeden nasıl check ederim ? if (players[1]) diyorum mesela ama players[1] tanımlanmadığı için hata raporu alıyorum. işte bu hata raporunu almadan bu pointer var mı yok mu nasıl kontrol ederim?


&players dersin, *players o pointerin gosterdigi yeri gosterir
&dirsen pointerin adresini gosterir.
Link to comment
Sosyal ağlarda paylaş

Kojiroh said:

Yani kodun tamamını göremediğim için çok da bi şey söyleyemiyorum aslında, üstelik asıl kodunda da orada yazdığındaki gibi sizeof yerine 5 yazmış mısın bilemiyorum.

Ama sizeof() kullanımı şart. Çünkü bi char bi int alan içeren her struct'ın 5 byte olacağını garanti edemezsin. Derleme esnasında structlar incelenirken, boyutları içlerindeki en geniş veri alanına göre düzenlenir ve ufak olanlar pad edilir. Örneğin o ASD struct'ı aslında 8 byte tutar, en büyük alan int olduğu için 1 byte'lık char'ı da ona göre pad eder. Ya da mesela:

typedef struct _asd {
char a; // 1
// 3 padding
int b; // 4
char c; // 1
// 3 padding
} asd;


Bu struct 12 byte'tır. Ama aşağıdaki gibi tanımlarsan 8 byte:

typedef struct _asd {
char a; // 1
char c; // 1
// 2 padding
int b; // 4
} asd;

Bu da 8 byte mesela:

typedef struct _asd {
char a; // 1
char c; // 1
short d; // 2
int b; // 4
} asd;


Bu tarz belirsizlikleri önlemek için, her zaman boyutu ufak olan verileri önce, büyük olanları sonra yazmak ve sizeof kullanmak şart.
http://en.wikipedia.org/wiki/Data_structure_alignment#Typical_alignment_of_C_structs_on_x86


@Buddha: Ezberden ziyade analitik düşünebilme önemli. Ezber de lazımdır muhtemelen ama programlama unsurlarının biçoğu zamanla pratikleşebilcek şeyler zaten. Mesela bu anlattığım şeye uymak için ilk başta hangi veri tipinin kaç byte tuttuğunu ezberlemen gerekebilir, ama zamanla yer eder. Ya da en kötü ihtimalle hangi tip hangi tipten daha fazla yer tutar onu bilirsin.


compiler'in sizeofunun doğru çalışmama gibi bir şansı var mı ? çünkü char ve int içeren structun size'ini 4 gösterip yine int alınırken bozukluk çıkarıyor. ama manuel olarak size'ı 8 yazınca düzeliyor.
Link to comment
Sosyal ağlarda paylaş

×
×
  • Yeni Oluştur...