לוגו אתר Fresh          
 
 
  אפשרות תפריט  ראשי     אפשרות תפריט  צ'אט     אפשרות תפריט  מבזקים     אפשרות תפריט  צור קשר     חץ שמאלה ‎print ‎"Hello World!"; if‎ ‎not rules.‎know ‎then rules.‎read(); חץ ימינה  

לך אחורה   לובי הפורומים > מחשבים > תכנות ובניית אתרים
שמור לעצמך קישור לדף זה באתרי שמירת קישורים חברתיים
תגובה
 
כלי אשכול חפש באשכול זה



  #1  
ישן 18-08-2010, 14:39
  kfir_z kfir_z אינו מחובר  
 
חבר מתאריך: 06.09.02
הודעות: 561
Winsock - בדיקה האם פורט פתוח עם טיימאאוט - visual c++

שלום לכולם,
אני רוצה לבצע דבר פשוט: פונקציה שמקבלת מחרוזת hostname ומחזירה BOOL - האם פורט פתוח על hostname או לא תוך זמן מוגדר. לצורך העניין הפורט הוא 135, ה-timeout הוא 1000 ms.
משום מה זה לא עובד..connect חוזרת אחרי הרבה יותר מ-1000 ms.


להלן הקוד:

BOOL Connect(char *hostname)
{
WSADATA wsaData;
WORD version;
int error;
SOCKET client;

version = MAKEWORD( 2, 0 );

error = WSAStartup( version, &wsaData );
if ( error != 0 )
{
// error occured
return FALSE;
}

if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 0 )
{
WSACleanup();
return FALSE;
}

client = socket( AF_INET, SOCK_STREAM, 0 );

struct hostent *host;

host = gethostbyname( hostname );

struct sockaddr_in sin;

memset( &sin, 0, sizeof sin );

sin.sin_family = AF_INET;
sin.sin_addr.s_addr = ((struct in_addr *)(host->h_addr))->s_addr;
sin.sin_port = htons(135);
int nRet2 = -1;
int nLen2 = sizeof(nRet2);
if(getsockopt(client, SOL_SOCKET, SO_SNDTIMEO, (char*)&nRet2, (int*)&nLen2) == 0)
printf("send timeout is %d\n", nRet2);
else
printf("error %d\n", WSAGetLastError());

int optval = 1000;
if(setsockopt(client, SOL_SOCKET, SO_SNDTIMEO, (char*)&optval, sizeof(int)) !=0)
{
printf("error %d", WSAGetLastError());
}

if(getsockopt(client, SOL_SOCKET, SO_SNDTIMEO, (char*)&nRet2, (int*)&nLen2) == 0)
printf("send timeout is %d\n", nRet2);
else
printf("error %d\n", WSAGetLastError());

if ( connect( client, (struct sockaddr *)&sin, sizeof sin ) == SOCKET_ERROR )
{
printf( "Failed to connect.\n" );
closesocket(client);
WSACleanup();
return FALSE;
}
else
printf("success\n");


closesocket(client);
WSACleanup();
return TRUE;
}

תודה מראש,
כפיר


נערך לאחרונה ע"י kfir_z בתאריך 18-08-2010 בשעה 14:46.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #2  
ישן 18-08-2010, 15:15
  שימיadmin שימי אינו מחובר  
מנהל פורומי "תכנות ובניית אתרים" ו"חומרה ורשתות"
 
חבר מתאריך: 25.10.01
הודעות: 42,775
בתגובה להודעה מספר 1 שנכתבה על ידי kfir_z שמתחילה ב "Winsock - בדיקה האם פורט פתוח עם טיימאאוט - visual c++"

אאל"ט SO_SNDTIMEO מתייחס ל timeout של write(), לא של connect(). (וגם לא ממומש בהכרח בכל פלטפורמה.)

הפתרון שאני מכיר, אם אתה רוצה לקבוע timeout מדוייק של שנייה אחת, הוא לפתוח את ה socket במצב NONBLOCK, לעשות connect() ואז פשוט להמתין שנייה אחת, לעשות עליו select(), ולראות מה מצבו... כמובן שאפשר לעשות את הבדיקה גם כל 100ms, נניח, כדי שאם זה כן נפתח בפחות משנייה (מה שבד"כ יקרה אם זה אכן נפתח), לא תחכה סתם שנייה שלמה.

דוגמה לקוד כזה: http://www.developerweb.net/forum/s...ead.php?p=13486 (אתה יכול לדלג לסוף הקוד שמחזיר את זה ל blocking, כי זה לא באמת מעניין אותך. אחרי שאתה יודע שה connect הצליח או לא, אתה מיד מעיף את החיבור, כך ש...)

אגב, אם אתה בטעות בונה "מכונת ניטור" ו/או סורק פורטים, יש כל כך הרבה כלים כאלה מוכנים ומצויינים (למשל nmap כסורק הפורטים האולטימטיבי, ושלל תוכנות ניטור שפשוט אין טעם להתחיל לפרט...)
_____________________________________
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה
נמאס לכם לזכור סיסמאות? לחצו כאן!

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #5  
ישן 19-08-2010, 11:35
  kfir_z kfir_z אינו מחובר  
 
חבר מתאריך: 06.09.02
הודעות: 561
בתגובה להודעה מספר 4 שנכתבה על ידי שימי שמתחילה ב "או שאתה לא הבנת אותי, או שאני..."

עובד! תודה על העזרה! אגב נראה לך שזמן של 100ms זה מספיק?
להלן קוד:

BOOL Connect(char *hostname)
{
WSADATA wsaData;
WORD version;
int error;
SOCKET client;
struct timeval tv;
struct fd_set myset;


version = MAKEWORD( 2, 0 );

error = WSAStartup( version, &wsaData );


if ( error != 0 )
{
return FALSE;
}

if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 0 )
{
WSACleanup();
return FALSE;
}

client = socket( AF_INET, SOCK_STREAM, 0 );

struct hostent *host;

if ((host = gethostbyname( hostname )) == NULL)
{
closesocket(client);
WSACleanup();
return FALSE;
}

struct sockaddr_in sin;

memset( &sin, 0, sizeof sin );

sin.sin_family = AF_INET;
sin.sin_addr.s_addr = ((struct in_addr *)(host->h_addr))->s_addr;
sin.sin_port = htons(135);
u_long iMode=1;
ioctlsocket(client, FIONBIO, &iMode);


error = connect( client, (struct sockaddr *)&sin, sizeof sin );

if(error < 0)
{
if(WSAGetLastError() == WSAEWOULDBLOCK)
{
tv.tv_sec = 0;
tv.tv_usec = 100000;
FD_ZERO(&myset);
FD_SET(client, &myset);
while(1)
{
error = select(client+1, NULL, &myset, NULL, &tv);
if (error < 0 && WSAGetLastError() != WSAEINTR)
{
printf("Error connecting %d\n", WSAGetLastError());
closesocket(client);
WSACleanup();
return FALSE;
}
else if (error > 0)
{
printf("success! %d\n", WSAGetLastError());
closesocket(client);
WSACleanup();
return TRUE;
}
error = WSAGetLastError();
}
}
else
{
printf("Error connecting %d\n", WSAGetLastError());
closesocket(client);
WSACleanup();
return FALSE;
}
}

closesocket(client);
WSACleanup();
return TRUE;
}


תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #6  
ישן 19-08-2010, 14:20
  שימיadmin שימי אינו מחובר  
מנהל פורומי "תכנות ובניית אתרים" ו"חומרה ורשתות"
 
חבר מתאריך: 25.10.01
הודעות: 42,775
בתגובה להודעה מספר 5 שנכתבה על ידי kfir_z שמתחילה ב "עובד! תודה על העזרה! אגב נראה..."

מספיק ל...מה ? לפתיחת חיבור?

פתיחת חיבור TCP נעשית בשלושה שלבים, פאקט לכל כיוון, כך שהפאקט השלישי בעצם נשלח, אני משער שהמע"ה תגדיר כבר שה socket נמצא במצב CONNECTED. לכן בעצם מדובר פה ב roundtrip בודד מבחינת השיהוי משליחת ה SYN Packet על ידי המחשב שיוצר את החיבור, ועד לעלייה למצב CONNECTED.

יש גם זמן עיבוד בדרך, שתלוי בתוכנות שמעבדות את הבקשות. שמועה ששמעתי (ומצד אחד קשה להאמין כי זה הזוי, ומצד שני, דוט נט... כבר ראיתי הכל), אומרת שפתיחת חיבור בדוט נט (כלומר C#) יוצרת שיהוי מטורף של כ 20ms (מול סדר גודל של 1 מילי ב C על לינוקס...). תוסיף לכך תנאי רשת, עומסים למיניהם, וכו'.

אם אתה מניח 100ms, זה אומר שאתה מניח שכל צד (עיבוד שליחה + שליחה + עומס רשת) עושה את את החלק שלו ב 50ms. וזה כולל כל מקרה קצה: גם שה CPU של המערכת המקבלת עמוס וכו'. גם כשיש הפצצות ברשת. גם ש...

ב LAN זה יחסית ריאלי, אבל כבר ראיתי דברים מעולם. השאלה היא כמה אקוטי לך "לפספס" מחשב בגלל שיהוי ארוך אליו, ולא משנה מה הסיבה.

אתה יכול לעשות על זה סטטיסטיקה קטנה, ונניח לעשות דגימה כל 50ms עם timeout של 250ms (שוב, אם זה LAN). אם התקשורת שלך יוצאת מעבר ל LAN, זה כבר סיפור אחר לגמרי. ה Roundtrip לאירופה הוא בסביבות ה 70-100ms. לחוף המזרחי של ארה"ב בין 160-200ms. לחוף המערבי בין 200-240ms. ולאוסטרליה - בין 400-460ms. ואם באיזשהוא שלב עוברים תמסורת לווינית, אתה מוזמן להפוך את הערכים האלה לשניות שלמות. וכל הנ"ל בתנאים אידאליים, כלומר, כשאין תקלות
_____________________________________
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה
נמאס לכם לזכור סיסמאות? לחצו כאן!

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
תגובה

כלי אשכול חפש באשכול זה
חפש באשכול זה:

חיפוש מתקדם
מצבי תצוגה דרג אשכול זה
דרג אשכול זה:

מזער את תיבת המידע אפשרויות משלוח הודעות
אתה לא יכול לפתוח אשכולות חדשים
אתה לא יכול להגיב לאשכולות
אתה לא יכול לצרף קבצים
אתה לא יכול לערוך את ההודעות שלך

קוד vB פעיל
קוד [IMG] פעיל
קוד HTML כבוי
מעבר לפורום



כל הזמנים המוצגים בדף זה הם לפי איזור זמן GMT +2. השעה כעת היא 10:59

הדף נוצר ב 0.18 שניות עם 12 שאילתות

הפורום מבוסס על vBulletin, גירסא 3.0.6
כל הזכויות לתוכנת הפורומים שמורות © 2024 - 2000 לחברת Jelsoft Enterprises.
כל הזכויות שמורות ל Fresh.co.il ©

צור קשר | תקנון האתר