Winsock - connect

זויברג

New member
Winsock - connect

יש לי בעיה נורא מוזרה. לא משנה לאיזה URL או כתובת IP אני מנסה להתחבר, הפונקציה connect מחזירה לי SOCKET_ERROR (ערך של 1-). עשיתי WSAStartup, הSokcet מאותחל כמו שצריך ונראה לי גם שהSOCKADDR_IN מוגדר כמו שצריך, אבל הפונקציה פשוט לוקחת לה איזה 20 שניות ואז מחזירה SOCKET_ERROR, אפילו לIPים מקומיים בתוך הרשת הביתית. מישהו נתקל פעם בבעיה הזאת? טעות בהגדרות אולי?
 

זויברג

New member
הנה

addr.sin_family = AF_INET; addr.sin_port = 80; RemoteHost = gethostbyname("www.walla.co.il"); RemoteHost = gethostbyaddr("192.168.1.1",4,AF_INET); sAddrBuff = new char[RemoteHost->h_length]; j = 0; while (RemoteHost->h_addr_list[j] != NULL) { for (i = 0; i < RemoteHost->h_length; i++) sAddrBuff = RemoteHost->h_addr_list[j]; addr.sin_addr.S_un.S_un_b.s_b1 = sAddrBuff[0]; addr.sin_addr.S_un.S_un_b.s_b2 = sAddrBuff[1]; addr.sin_addr.S_un.S_un_b.s_b3 = sAddrBuff[2]; addr.sin_addr.S_un.S_un_b.s_b4 = sAddrBuff[3]; if (connect(mainSocket,(SOCKADDR *)&addr,sizeof(addr)) != SOCKET_ERROR) break; j++; } if (RemoteHost->h_addr_list[j] == NULL) throw new MyErr("Cannot connect to the HTTP server",0);
 

זויברג

New member
רק בלי השורה:

RemoteHost = gethostbyaddr("192.168.1.1",4,AF_INET);​
היא רק לשימוש במקרה של DEBUG (כתובת IP פנימית בתוך הרשת הביתית)...
 

זויברג

New member
10060 = WSAETIMEDOUT

קיבלתי שגיאת WSATIMEDOUT. לפי MSDN, זה ההסבר לשגיאה, אבל מה יכול לגרום לשגיאה הזאת? הקוד| Connection timed out. A connection attempt failed because the connected party did not properly respond after a period of time, or the established connection failed because the connected host has failed to respond. |
 

_alon_

New member
אתה צריך להמיר דברים ל

network byte order. לדוגמא:
SOCKADDR_IN stDstAddr; stDstAddr.sin_family = PF_INET; stDstAddr.sin_port = htons(80); stDstAddr.sin_addr.s_addr = inet_addr("172.16.12.90");​
 

זויברג

New member
מעניין,

הוספתי את htons להשמה של המספר פורט, ופתאום ההתחברות עובדת. מה htons עושה?
 

_alon_

New member
מתוך ה-MSDN

The htons function converts a u_short from host to TCP/IP network byte order (which is big-endian). אם נפשט(!) את רעיון big-endian and little endian אז: נניח ויש לך משתנה בעל ערך 1234 ותאים בזכרון שיכולים להכיל 2 ספרות. נחליט שנאחסן את המשתנה כ-12 בתא אחד ו-34 בתא אחר. עכשיו נחליט על תקן שיקבע מי מהתאים בעל הערך היותר גדול (אלפים ומאות מול עשרות ואחרות) כלומר האם המספר שאנו מאחסנים יאוחסן כ-1234 או 3412. אתה לא "דיברת" בתקן של Winsock ולמעשה פנית לפורט אחר, נניח במקום לפנות ל-1234 פנית ל-3412. הפונקציה htons סידרה את הערך שלך לתקן של winsock.
 

voguemaster

New member
עצה

בקוד שלך אתה מעתיק בצורה די חאפרית את המערך h_addr_list בכל פעם שאתה מנסה לבצע connect. זה ממש לא רעיון טוב. אז ראשית, כדאי שתדע שכשאתה מקבל struct hostent * שיש בו איברים מלאים, כלומר כתובת IP, היא ב-network byte ordering ולכן אפשר ורצוי להעתיק אותה עם memcpy, כך:
RemoteHost = gethostbyname("www.walla.co.il"); memcpy(&addr.sin_addr, &h_addr_list[0], sizeof(struct in_addr));​
ואם יש לך יותר מאיבר אחד ב-h_addr_list אתה תמיד יכול להעתיק עוד אם אתה ממש רוצה. לרוב אין גם ככה..
 
למעלה