בעיה מציקה!

nadavwexler

New member
בעיה מציקה! ../images/Emo10.gif

אני מנסה להבין כבר כמה זמן איך מקבלים ip address משם של מחשב.... הצלחתי לקבל כל מיני דברים אבל לא ip! אם מישהו מוכן יהיה נחמד לקבל קטע קוד או הסבר על איך זה נעשה באמצעות winsock.... ועוד משו: למה מיקרוסופט לא הוציאה getaddrbyname?!? תודה מראש, נדב.
 

voguemaster

New member
שים לב..

הפונקציה gethostbyname מחזירה את כתובת ה-IP של המחשב במידה ויש כזו ולמחשב שלך יש גישה לשרת DNS. כתובת ה-IP נמצאת במבנה מסוג in_addr. בכל מקרה, אפשר להשתמש ב-inet_ntoa כדי לבצע את ההמרה למחרוזת קריאה. אני לא זוכר בדיוק אבל נדמה לי שהפוקנציה הזו לא בטוחה לשימוש בתוכניות של כמה threads אז זהירות מומלצת.. (או לכתוב WRAPPER שמבטל את העניין, או להשתמש ב-inet_ntop..). ד"א, המבנה (מבנה פשוט מאוד סה"כ) שמכיל את in_addr מוחזר תמיד במה שנקרא network byte ordering, זה למעשה הסידור של הבתים בפנוכו. טוב כרגע זה לא כ"כ חשוב לעניין שלך אבל רק שתדע שיש הבדל בין המוסכמות הזו לבין הסידור של הבתים בפלטפורמות שונות (PC לדוגמא מסדר אותם הפוך!).
 

voguemaster

New member
כלומר, שכחתי את הקוד ../images/Emo13.gif

משהו בסגנון (כמו כן קבל תיקון טעות, שכחתי את סוג המבנה שמתקבל, לפחות ביוניקס (אבל עד כמה שידוע לי זה דומה ב-WINSOCK כי זה אותו API)):
struct hostent *host; char hostname[]="www.tapuz.co.il"; host = gethostbyname( hostname); if ( host == NULL) { // resolving error or no IP found, check error // do some work if error occured.. } else { // print the IP printf("%s´s IP address: %s\n", hostname, inet_ntoa( host->h_addr_list[0])); }​
השורה שמדפיסה משתמשת ב-inet_ntoa להפוך את המבנה שמכיל את הכתובת למחרוזת. h_addr_list זה מערך של מבנים שמכילים כתובות IP לשם הזה, בד"כ יש רק את האיבר הראשון אבל לפעמים יש כמה כתובות IP לשם אחד... שים לב לדברים הבאים: 1. הפונציה gethostbyname וחברתה gethostbyaddr הן לא פונקציות בטוחות לשימוש בקוד עם כמה threads בגלל שהן מחזירות מצביע למבנה סטטי מסוג hostent. 2. הפונקציה inet_ntoa גם לא בטוחה מסיבה דומה. המשתנה המוחזר הוא מחרוזת, כלומר מצביע ל-char וגם הוא מוגדר כסטטי. בד"כ עדיף להשתמש בפונקציה עוטפת שמשתמשת באופן פנימי ב-inet_ntop...
 

nadavwexler

New member
אבל זה לא עובד! ../images/Emo4.gif

קודם כל, אני עובד ב pc.... ניסיתי את הקוד הבא: #include <stdio.h> #include <winsock2.h> int main() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 1, 1 ); err = WSAStartup( wVersionRequested, &wsaData ); hostent *a=gethostbyname("pc4"); if (a!=NULL) { printf("%s\n",inet_ntoa(a->h_addr_list[0])); WSACleanup(); } return 0; } ואני מקבל טעות שאין אפשרות להמיר מ char* ל in_addr..... האמת שניסיתי כבר לפני הפניה לפה את הקוד הנ"ל....
 

nadavwexler

New member
הצלחתי! ../images/Emo13.gif

אחרי כמה זמן הצלחתי להבין את ההיגיון מאחורי התוכנית!
והצלחתי ליצור משו שמשיג את כתובת ה ip... הקטע הוא שצריך להעביר את 4 הבייטים הראשונים לתוך מבנה in_addr ורק אז להעביר ל inet_ntoa... בכל מקרה, הקובץ לעיונכם... :)
 

voguemaster

New member
בדיוק עמדתי לכתוב לך על זה..

שים לב להגדרה של hostent:
struct hostent { char FAR * h_name; char FAR * FAR * h_aliases; short h_addrtype; short h_length; char FAR * FAR * h_addr_list; };​
ההגדרה של h_addr_list היא מערך של char*. הסיבה היא (עכשיו בדקתי) בגלל שהמבנה הזה עתיק יותר מ-ANSI C ולכן לא היה מה שייצג את in_addr. בכל אופן, אני מציע את הקוד הבא:
struct hostent *host; struct in_addr ipaddr; // do query host = gethostbyname( "www.tapuz.co.il"); if ( host != NULL) { // print memcpy( &ipaddr, host->h_addr_list[0], host->h_length); printf("IP address is %s\n", inet_ntoa( ipaddr)); }​
אחרי שראיתי את ה-PROTOTYPE הלכתי לקוד שכבר כתבתי ובדקתי. מסתבר שאני העתקתי בצורה הנ"ל את כתובות ה-IP למשתנים לוקאליים ורק אז עבדתי איתם (זה חשוב בגלל ריבוי threads..). בכל אופן אפשר גם לעשות משהו כזה:
printf("IP is %s\n", inet_ntoa( *(host->h_addr_list[0])) );​
ואם אתה מתעקש לעבור על כל הרשימה, הכי פשוט:
struct hostent *pHost; char **pptr; pptr = pHost->h_addr_list; for( ; *pptr != NULL ; pptr++) printf("IP is %s\n", inet_ntoa( *pptr));​
רואה, טוב ששאלת. הזכרת לי משהו שאסור היה לי לשכוח
 

nadavwexler

New member
תודה!! ../images/Emo13.gif

ועל לא דבר על ההזכרה..... בכל מקרה, הצלחתי לעשות בהצלחה די טובה את מה שרציתי אז אני מאוד שמח!
תודה!
 
למעלה