130 likes | 174 Views
Java Sockets. תכנות מתקדם 2 89-211 תרגול מספר 3 תש"ע 2009-2010. אליהו חלסצ'י. בשיעור היום נראה דוגמת low-level ליצירת תקשורת בין תוכנית שרת ולקוח ב java מעל פרוטוקול TCP Java מאפשרת לנו להשתמש ב sockets שמהווים אבסטרקציה לטרמינלים של חיבור תקשורת. הקדמה.
E N D
Java Sockets תכנות מתקדם 2 89-211תרגול מספר 3 תש"ע 2009-2010 אליהו חלסצ'י
בשיעור היום נראה דוגמת low-level ליצירת תקשורת בין תוכנית שרת ולקוח ב java מעל פרוטוקול TCP Java מאפשרת לנו להשתמש ב sockets שמהווים אבסטרקציה לטרמינלים של חיבור תקשורת. הקדמה
Socket מהווה נקודת קצה עבור חיבור תקשורת דו-כיוונית בין שתי תוכנות ברשת. ה Socket קשור ל port בכדי ששכבת ה TCP תכיר את האפליקציה שעושה בה שימוש. נכיר שתי מחלקות (המבוססות stream) ServerSocket עבור תוכנת השרת. Socket עבור הלקוח. הקדמה
נרצה להריץ בצד השרת תוכנה שתקבל בקשות ותשלח תגובות מתאימות ע"פ פרוטוקול כלשהו. לשם כך נצטרך: ליצור ServerSocket לבצע .accept() שימתין עד לחיבור הלקוח. לפתוח in/output stream עבור ה socket. לקרוא ולכתוב ל streams ע"פ הפרוטוקול. לסגור את ה streams ואת ה socket אם נרצה שרת שתומך בכמה לקוחות נצטרך לאחר כל accept לבצע את יתר הצעדים ב thread אחר... צד השרת
ניצור את המחלקהSocketServer. ננסה לפתוח ServerSocket בport 4444. אם הוא תפוס ייזרקexception. צד השרת package server; import java.net.* ; import java.io.* ; publicclass SocketServer{ publicstaticvoid main(String[]args) throws IOException { ServerSocket serverSocket=null; PrintWriter out = null; BufferedReader in = null; try { serverSocket = new ServerSocket(4444); System.out.println("Server started"); } catch (IOException e) { System.err.println("Cannot listen on port 4444"); System.exit(-1); }
המשך: ננסה לבצע accept. אם יצליח אז נקבלclientSocket חדשעבורהלקוח שהתחבר זה עתה. ממנו נקבל את ה streams. כעת ניתן להמשיך לרוץע"פ הפרוטוקול נעשה זאתע"י אובייקט אחר. נתפוס exception אםה accept לא הצליח. נסגור את clientSocketואת serverSocket. צד השרת Socket clientSocket=null; try { clientSocket=serverSocket.accept(); out=new PrintWriter( clientSocket.getOutputStream(),true); in=new BufferedReader(new InputStreamReader( clientSocket.getInputStream())); // server code here... MyProtocol mp=new MyProtocol(in,out); mp.run(); } catch (IOException e) { System.err.println("Accept failed"); System.exit(-1); } finally { if (clientSocket != null) clientSocket.close(); if (serverSocket != null) serverSocket.close(); } } }
MyProtocol: נקבל את ה streamsב CTOR. במתודה run נריץלולאה הקוראת מהinput וכותבת לoutput ע"פ פרוטוקולכרצוננו. hello world!Alice Bob!Exit bye! צד השרת package server; import java... publicclass MyProtocol { BufferedReader in; PrintWriter out; HashMap<String,String> hm; public MyProtocol(BufferedReader in, PrintWriter out){ this.in=in; this.out=out; hm=new HashMap<String,String>(); hm.put("hello", "world!"); hm.put("Alice", "Bob!"); hm.put("Exit", "bye!"); } publicvoid run(){ String request="",response=""; try { while(!request.startsWith("Exit")){ request=in.readLine(); response=hm.get(request); if(response!=null) out.println(response); elseout.println("?"); } } catch (IOException e) {} }}
נרצה להריץ בצד הלקוח תוכנה השולחת בקשות לשרת. לשם כך נצטרך: ליצור Socket. לפתוח עבורו streams. לקרוא ולכתוב אליהם ע"פ פרוטוקול השרת. לסגור את ה streams ואת ה socket. צד הלקוח
ניצור את המחלקהSocketClient. ננסה לפתוח Socketעבור ה IP של השרת ב port 4444. ממנו נקבל את הin/output streams. ומכאן מתחיל קודהלקוח. צד הלקוח package client; import java.io.* ; import java.net.* ; publicclass SocketClient { publicstaticvoid main(String[]args) throws IOException { Socket socket=null; PrintWriter out=null; BufferedReader in =null; String host = "localhost";// or IP address try { socket = new Socket(host,4444); out = new PrintWriter(socket.getOutputStream(),true); in = new BufferedReader(new InputStreamReader( socket.getInputStream())); // client code… System.out.println("client started"); MyProtocol mp=new MyProtocol(in,out); mp.run(); }
אם לא הצלחנו למצואאת השרת או לפתוחאת ה streamsנתפוס את הexception המתאים. לבסוף נסגור את הstreams ואת ה socket. צד הלקוח catch (UnknownHostException e) { System.err.println("Dont know host: "+host); System.exit(-1); } catch (IOException e) { System.err.println("Cannot get IO for connection to "+host); System.exit(-1); } finally { // close connection (Order important) if (out != null) out.close(); if (in != null) in.close(); if (socket!= null) socket.close(); } } }
MyProtocol: נקבל את ה streamsב CTOR. ב run נקלוט מחרוזותמהמשתמש, נכתובל out ונדפיס אתהתגובה מה in למסך עד שהשרת יחזירbye צד הלקוח package client; import java... publicclass MyProtocol { BufferedReader in;PrintWriter out; public MyProtocol(BufferedReader in, PrintWriter out){ this.in=in;this.out=out; } publicvoid run(){ BufferedReader sysin = new BufferedReader(new InputStreamReader(System.in)); String request=null,response=null; try { while(response==null || !response.startsWith("bye")){ System.out.print(">"); request=sysin.readLine(); out.println(request); response=in.readLine(); System.out.println(response); } } catch (IOException e) { }}}
נריץ את תוכנת השרת, ואז את תוכנת הלקוח: ריצה client started >hello world! >Alice Bob! >something else ? >Exit bye! server started hello world! Alice Bob! something else ? Exit bye! SocketClient SocketServer
התאימו את קוד השרת כך שיטפל בעד 10 לקוחות בו"ז. הוסיפו תמיכה בפקודה upload <FileName>שתעביר לשרת את הקובץ המבוקש. הטמעה