340 likes | 635 Views
מערכות הפעלה. תרגול 14 – תקשורת, מנגנוני תקשורת ב- Linux. תוכן התרגול. מודל השכבות מודל כללי שכבה פיזית שכבת רשת ( IP ) שכבת Transport שכבת אפליקציה סיכום מודל השכבות מושג ה- socket מנגנון תקשורת ב- Linux API Network מבנה שרת מבנה לקוח מדריך מועיל בנושא נמצא ב- URL :
E N D
מערכות הפעלה תרגול 14 – תקשורת, מנגנוני תקשורת ב-Linux
תוכן התרגול • מודל השכבות • מודל כללי • שכבה פיזית • שכבת רשת (IP) • שכבת Transport • שכבת אפליקציה • סיכום מודל השכבות • מושג ה-socket • מנגנון תקשורת ב-Linux • APINetwork • מבנה שרת • מבנה לקוח • מדריך מועיל בנושא נמצא ב-URL: http://www.ecst.csuchico.edu/~beej/guide/net/html/ מערכות הפעלה - תרגול 13
הקדמה • בצורה המופשטת ביותר רשת תקשורת היא אוסף חיבורים, המאפשר תקשורת בין המחשבים. • העברת נתונים ברשת תקשורת מבוצעת באמצעות פרוטוקולי תקשורת. • הפרוטוקולים פועלים בשכבות שונות, כשלכל שכבה תפקיד משלה. • אוסף פרוטוקולי תקשורת הנפוץ ביותר נקרא TCP/IP. • נלמד את חלוקה לשכבות של TCP/IP ואת הפרוטוקולים הפועלים בשכבות השונות. מערכות הפעלה - תרגול 13
מודל השכבות (1) • מודל השכבות הוא מודל סטנדרטי המאפשר לחלק את פרוטוקולי התקשורת לקבוצות או שכבות, כאשר לכל שכבה תפקיד משלה. • מודל השכבות של TCP/IP מכיל 4 שכבות מערכות הפעלה - תרגול 13
Source Destination Application Application Transport Transport Internet Internet Net. Access Net. Access מודל השכבות (2) • כל שכבה מקבלת שירותים מהשכבה שמתחתיה, מספקת שירותים לשכבה שמעליה, ו"מדברת" עם השכבה המקבילה במחשב השני. מערכות הפעלה - תרגול 13
שכבת גישה לרשת -Network Access • תפקידה להעביר חבילה מתחנה נוכחית לתחנה שכנה באותה רשת. • השכבה מטפלת בכל הפרטים הקשורים בחומרה ובממשק עם הרשת הפיסית. • הפרוטוקול בשכבה זו שונה מרשת לרשת ותלוי בחומרה של הרשת הפיסית. מערכות הפעלה - תרגול 13
שכבת Internet - פרוטוקול IP • שכבת Internet אחראית על ניתוב חבילות מתחנת המקור לתחנת היעד. • הפרוטוקול בשכבה זו נקרא- Internet Protocol IP. • פרוטוקול IP מאפשר ניתוב חבילות בין רשתות שונות, באמצעות Gateways. • Gateways הם מחשבים מיוחדים שמחברים בין רשתות שונות ומאפשרים העברת חבילות בין הרשתות • הפרוטוקול לא מבטיח שחבילה תגיע אל יעדה, הוא רק מחליט איך לנתב כל חבילה. • פרוטוקול IP הוא connectionless, מכיוון שכל חבילה מנותבת בנפרד, ללא קשר לחבילות אחרות. מערכות הפעלה - תרגול 13
כתובת IP • פרוטוקול IP מבצע את הניתוב על סמך כתובת IP • כתובת IP היא מספר המזהה בצורה חד-ערכית כל ממשק תקשורת שמחובר לרשת. • למחשב אחד יכולים להיות מספר כתובות IP, לדוגמה אם יש לו מספר כרטיסי רשת. • גודל של כתובת IP הוא 32 סיביות. • מקובל לייצג כתובת IP ע“י 4 מספרים עשרוניים • לדוגמה : 132.68.37.66 מערכות הפעלה - תרגול 13
טבלאות ניתוב • ההחלטה איך לנתב חבילה מתקבלת על סמך טבלאות ניתוב מיוחדות(routing tables) , הקיימות בכל מחשב שיכול לשמש כ-router • router הינו מחשב שדרכו עוברות חבילות שלא מיועדות למחשב עצמו. • ל – router יהיו בד"כ מספר ממשקי תקשורת. • טבלאות הניתוב מאפשרות להחליט לאן לשלוח את החבילה לפי כתובת ה-IP שלה. • אתם יכולים לגלות כמה ממשקי תקשורת יש למחשב ומה כתובות ה-IP שלהם ע"י שימוש בפקודה ifconfigבתוך shell של Linux. מערכות הפעלה - תרגול 13
שכבת Transport • מאפשרת תקשורת ברמה של תהליכים (להבדיל משכבת IP שמאפשרת תקשורת בין מחשבים בלבד) • בשכבה זו שני פרוטוקולים עיקריים : UDP ו- TCP (בו נתמקד) • TCP הוא connection oriented , הוא יוצר session בין שני תהליכים. • TCP מבטיח: • סדר - החבילות יגיעו ליעדן בסדר שבו נשלחו • אמינות - כל החבילות יגיעו (חבילה שהולכת לאיבוד משודרת מחדש) מערכות הפעלה - תרגול 13
מהו port • כפי שנאמר, כתובת IP מזהה מחשב בצורה חד משמעית. • אבל, מחשב יכול להריץ מספר אפליקציות המעבירות מידע דרך הרשת. איך מזהים חבילות השייכות לאפליקציה מסוימת? • port הינו מושג וירטואלי המאפשר שימוש ברשת ע“י מספר אפליקציות במקביל. • עבור כל אחד מהפרוטוקוליםUDP ו-TCP מוגדרת סדרה של פורטים במספרים 0 עד 65535. • חלק מהפורטים שמורים לאפליקציות מסוימות: • telnet – port 23, ftp – port 21 , http – port 80. • יישומי משתמש יכולים להשתמש רק במספרי פורטים הגדולים מ – 1023. מערכות הפעלה - תרגול 13
שימוש בפורטים • תהליך שמעוניין לאפשר לתהליכים מרוחקים להתחבר אליו, מגדיר מספר פורט שעליו הוא "מקשיב". • רק תהליך אחד יכול "להקשיב" על כל פורט. • תהליך שרוצה להתחבר לתהליך שמקשיב, שולח חבילה שכתובת היעד שלה היא כתובת ה- IP של המחשב עליו רץ המקשיב, ומספר פורט היעד הוא מספר הפורט עליו התהליך "מקשיב". • שכבת ה- transport שמקבלת חבילה מזהה לפי כתובת ה – IP ומספר הפורט לאיזה תהליך להעביר את החבילה. מערכות הפעלה - תרגול 13
שכבת האפליקציה • מכילה פרוטוקולים של אפליקציות כגון: • telnet, ftp, http ואחרות. • אפליקציות אלה משתמשות בפרוטוקולי transport לתקשורת עם מחשבים מרוחקים. מערכות הפעלה - תרגול 13
Source Destination Application Application Transport Transport Internet Internet Internet Internet Net. Access Net. Access Net. Access Net. Access מודל השכבות - סיכום מערכות הפעלה - תרגול 13
מושג ה - socket • ניקח לדוגמה שרת telnet, השרת הנ"ל "מקשיב" על פורט 23 לבקשות התחברות. • כשמתקבלת בקשת התחברות נוצר telnet session בין השרת ללקוח שהתחבר. • נרצה לאפשר למספר לקוחות להתחבר לאותו שרת telnet בו זמנית. • על-מנת שניתן יהיה לנהל מספר sessions במקביל, משתמשים ב-sockets. • socket מוגדר ברמה של אפליקציה (ולא ברמת המערכת כמו port) והוא מאפשר לאפליקציה להבדיל בין sessions שונים. • לכל session מתאים זוג sockets בשרת ובלקוח. מערכות הפעלה - תרגול 13
מימוש של תקשורת ב- Linux • Linux תומכת במספר רב של ארכיטקטורות רשת. • נתמקד על התמיכה ש-Linux מספקת לארכיטקטורת TCP/IP: • קריאות מערכת המאפשרות יצירת תקשורת עם תהליכים מרוחקים. • מבני נתונים המשמשים את קריאות המערכת הנ"ל • כל קריאות המערכת שנראה משתמשות ב-sockets. • תחילה נגדיר את ה-socket, ואח"כ נחבר אותו לפורט המתאים מערכות הפעלה - תרגול 13
Networking API של Linux • עבור כל הקריאות יש צורך להוסיף : #include <sys/types.h> #include<sys/socket.h> • יצירת socket חדש : int socket(int family, int type, int protocol) • ערך חזרה : במקרה של הצלחה – מחזיר descriptor המצביע ל-socket החדש • ה-descriptor שמוקצה שייך ל-PDT של התהליך כמו descriptors אחרים המצביעים על קבצים פתוחים, pipes, ... . מערכות הפעלה - תרגול 13
Networking API של Linux פרמטרים: • family - מגדיר את ארכיטקטורת הרשת שדרכה תתבצע תקשורת. נשתמש תמיד ב-AF_INET. • type – מגדיר את מודל התקשורת ברשת. • SOCK_STREAM עבור תקשורת connection oriented , מבוססת stream ואמינה. • ממומשת ע"י TCP • protocol - מגדיר את פרוטוקול התקשורת של שכבת Transport. • העברת 0 בתור פרמטר יגרום לבחירת הפרוטוקול ברירת מחדל • TCP עבור SOCK_STREAM מערכות הפעלה - תרגול 13
Networking API של Linux קישור של socket ל – port : int bind(int sockfd, struct sockaddr * my_addr, int addrlen) פרמטרים: • sockfd – ה-descriptor של ה-socket אותו מחברים. • my_addr – כתובת אליה מקשרים. הכתובת מכילה את כתובת ה-IP של המחשב ואת מספר ה-port אליו יקושר ה-socket • יש להכניס תמיד את ה-IP של המחשב המקומי • addrlen – אורך של my_addr בבתים. ערך חזרה: מוחזר 0 במקרה של הצלחה, 1- במקרה של כישלון. מערכות הפעלה - תרגול 13
Networking API של Linux פקודת listen(): int listen(int sockfd, int num) פעולה: הצהרת כוונה לקבל בקשות תקשורת והגדרת אורך תור מקסימלי של בקשות ממתינות. פרמטרים: • sockfd – ה-descriptor של ה-socket • num – מספר מקסימלי של בקשות התחברות ממתינות ערך חזרה:מוחזר 0 במקרה של הצלחה, 1- במקרה של כישלון. מערכות הפעלה - תרגול 13
Networking API של Linux קריאת accept(): int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) פעולה: מחכה על ה-socket הנתון לבקשות תקשורת. כשיש בקשות בתור הבקשות הממתינות: • מוציא בקשה מהתור • יוצר socket חדש ומקצה לו descriptor חדש. • ה-socket החדש ישמש לתקשורת עם שולח הבקשה • ה-socket ה"ישן" לא מושפע ע"י הקריאה הנ"ל מערכות הפעלה - תרגול 13
Networking API של Linux פרמטרים: • sockfd – ה-descriptor של ה-socket עליו מחכים לבקשות תקשורת • addr – כתובת של שולח של בקשת תקשורת שהתקבלה. • מוחזר כתוצאה מהקריאה. • addrlen – אורך של הכתובת בבתים. ערך חזרה: במקרה של הצלחה מוחזר ה-descriptor של ה-socket החדש שנוצר, אחרת מוחזר 1-. מערכות הפעלה - תרגול 13
Networking API של Linux קריאת connect(): int connect(int sockfd, const struct sockaddr* serv_addr, socklen_t addrlen) פעולה: מנסה ליצור תקשורת עם תהליך שמקשיב על הכתובת serv_addr. • זכרו שכתובת מורכבת מכתובת IP ומספר port. פרמטרים: • sockfd – ה-descriptor של socket • serv_addr – הכתובת שעליה התהליך איתו מנסים ליצור תקשורת מקשיב. • addrlen – אורך של כתובת בבתים. ערך חזרה: במקרה של הצלחה מוחזר 0, במקרה של כשלון 1-. מערכות הפעלה - תרגול 13
Networking API של Linux כתיבה ל-socket : • ניתן לכתוב ל-socket באמצעות קריאת write שלמדנו לכתיבה לקבצים. כאשר ה-descriptor שמועבר הוא descriptor של ה-socket השולח, וההודעה תועבר ל-socket אליו מקשיב התהליך השני. קריאת send() : int send(int sockfd,const void *msg, size_t len, int flags) פעולה: כמו write, למעט אפשרות שימוש בדגלים לפעולות שליחה מיוחדות. ערך חזרה: במקרה של הצלחה מספר הבתים שנשלחו, אחרת 1-. מערכות הפעלה - תרגול 13
Networking API של Linux קריאה מה-socket: • ניתן לקרוא מה-socket באמצעות קריאת read שלמדנו לקריאה מקבצים. • ה-descriptor שמועבר הוא descriptor של ה-socket הקורא. • ה-socket חייב להיות מחובר (connected) ל- socket אחר. קריאת recv() : int recv(int sockfd, void *buf, size_t len, int flags) פעולה: כמו read, למעט אפשרות שימוש בדגלים לפעולות קריאה מיוחדות. ערך חזרה: במקרה של הצלחה מספר הבתים שנקראו, אחרת 1-. מערכות הפעלה - תרגול 13
Networking API של Linux סגירת socket : הפקודה המשמשת לסגירת socket היא intclose (int sockfd) פעולה:סוגרת את התקשורת עם המחשב המרוחק ומשחררת את ה-descriptor שהצביע על ה-socket. פרמטר: • sockfd – ה-descriptor של ה- socket לסגירה. ערך חזרה: במקרה של הצלחה 0, אחרת 1- מערכות הפעלה - תרגול 13
מודל שרת לקוח (client/server) • מודל שרת/לקוח מתאר מצב שבו תהליך אחד, שהוא הלקוח, מבקש שירות מתהליך אחר, שהוא השרת. • תהליך השרת נותן שירות לתהליך הלקוח. • קיים מגוון רב של שרתים. השרתים המוכרים הם: שרתי telnet , שרתי web , שרתי ftp. • השרת בד"כ יודע לטפל בבקשות של מספר לקוחות בו זמנית. • נראה דוגמה של מימוש של שרת ולקוח פשוטים. מערכות הפעלה - תרגול 13
מימוש של שרת(1) #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> void error(char *msg) { perror(msg); exit(1); } int main(int argc, char *argv[]) { int sockfd, newsockfd, portno, clilen; char buffer[256]; struct sockaddr_in serv_addr, cli_addr; int n; if (argc < 2) { fprintf(stderr,"ERROR, no port provided\n"); exit(1); } מערכות הפעלה - תרגול 13
מימוש של שרת (2) sockfd = socket(AF_INET,SOCK_STREAM,0); if (sockfd < 0) error("ERROR opening socket"); bzero((char *) &serv_addr, sizeof(serv_addr)); portno = atoi(argv[1]); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) error("ERROR on binding"); listen(sockfd,5); clilen = sizeof(cli_addr); מערכות הפעלה - תרגול 13
מימוש של שרת (3) newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); if (newsockfd < 0) error("ERROR on accept"); bzero(buffer,256); n = read(newsockfd,buffer,255); if (n < 0) error("ERROR reading from socket"); printf("Here is the message: %s\n",buffer); n = write(newsockfd,"I got your message",18); if (n < 0) error("ERROR writing to socket"); return 0; האם הקוד הנ"ל תמיד יעבוד נכון? מערכות הפעלה - תרגול 13
מימוש של הלקוח (1) #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> void error(char *msg) { perror(msg); exit(0); } int main(int argc, char *argv[]) { int sockfd, portno, n; struct sockaddr_in serv_addr; struct hostent *server; char buffer[256]; מערכות הפעלה - תרגול 13
מימוש של הלקוח (2) if (argc < 3) { fprintf(stderr,"usage %s hostname port\n", argv[0]); exit(0); } portno = atoi(argv[2]); sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) error("ERROR opening socket"); server = gethostbyname(argv[1]); if (server == NULL) { fprintf(stderr,"ERROR, no such host\n"); exit(0); } bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; מערכות הפעלה - תרגול 13
מימוש של הלקוח (3) bcopy((char *)server->h_addr, (char *) &serv_addr.sin_addr.s_addr, server->h_length); serv_addr.sin_port = htons(portno); if (connect(sockfd,&serv_addr,sizeof(serv_addr)) < 0)( error("ERROR connecting"); n = write(sockfd,”HELLO THERE”,sizeof(“HELLO THERE”)); if (n < 0) error("ERROR writing to socket"); bzero(buffer,256); n = read(sockfd,buffer,255); if (n < 0) error("ERROR reading from socket"); printf("%s\n",buffer); return 0; } האם הקוד הנ"ל תמיד יעבוד נכון? מערכות הפעלה - תרגול 13