_ 2.1.1 Stream sockets på klientsidan Vi ska nu titta på den första huvudtypen av lågnivåkopplingar som kallas stream sockets. De använder protokollet TCP för transporten av datapaket vilket innebär: - Att uppkopplingen implementerar/simulerar en kontinuerlig "telefon"-uppkoppling - Att de är säkra, datapaketen kommer fram och de sätts ihop i rätt ordning - Att de (därmed blir) något långsamma Vi ska även titta på klient-server-paradigmen (men det är inget måste för denna typ av sockets) och vi börjar på klientsidan. __ Uppgift Gör ett program som implementerar en chattklient som kan sända och ta emot textmeddelanden. Chattklienten ska koppla upp sig till en chattserver via en stream socket. När en chattklient sänder ett textmeddelande till chattservern så sänder chattservern detta textmeddelande till alla anslutna chattklienter. Chattklienten ska alltså både kunna: - Sända textmeddelanden till chattservern - Ta emot textmeddelanden från chattservern och visa dessa textmeddelanden för användaren Chattklienten ska gå att startas på tre sätt: = §java Client§ (då ska host default bli §127.0.0.1§ och port default bli §2000§) = §java Client § (då ska port default bli §2000§) = §java Client § Efter detta ska chattklienten försöka koppla sig till chattservern. Om kopplingen lyckas så ska användaren informeras om vilken server och port man är uppkopplad till (exempelvis i titelraden om programmet är GUI-baserat). Om kopplingen inte lyckas så ska programmet avslutas. Frivillig utökning är att även ta med så att chattklienten klarar av om kopplingen bryts till chattservern (exempelvis om chattservern avslutas) genom att exempelvis meddela användaren och avsluta sig själv. En annan frivillig utökning är att implementera att chattklienten läser upp meddelandena med talsyntes. __ Exempel Ett enkelt exempel kan köras enligt följande: = Hämta filen: §[Client.jar, 05_ass/ip1/2/2.1.1/Client.jar]§ = Kör programmet med: §java -jar Client.jar§ Observera! Chattservern måste vara igång innan man startar chattklienten, se nedan. Ett exempel på en chattklient med talsyntes kan köras med hjälp av: - [Wikipedia: Java Speech API, http://en.wikipedia.org/wiki/Java_Speech_API] - [FreeTTS 1.2, http://freetts.sourceforge.net/] Hämta först filerna: - §[cmu_time_awb.jar, 05_ass/ip1/2/2.1.1/speech/cmu_time_awb.jar]§ - §[cmu_us_kal.jar, 05_ass/ip1/2/2.1.1/speech/cmu_us_kal.jar]§ - §[cmudict04.jar, 05_ass/ip1/2/2.1.1/speech/cmudict04.jar]§ - §[cmulex.jar, 05_ass/ip1/2/2.1.1/speech/cmulex.jar]§ - §[cmutimelex.jar, 05_ass/ip1/2/2.1.1/speech/cmutimelex.jar]§ - §[en_us.jar, 05_ass/ip1/2/2.1.1/speech/en_us.jar]§ - §[freetts.jar, 05_ass/ip1/2/2.1.1/speech/freetts.jar]§ - §[jsapi.jar, 05_ass/ip1/2/2.1.1/speech/jsapi.jar]§ - §[Client.class, 05_ass/ip1/2/2.1.1/speech/Client.class]§ - §[Client$L1.class, 05_ass/ip1/2/2.1.1/speech/Client$L1.class]§ - §[Client$L2.class, 05_ass/ip1/2/2.1.1/speech/Client$L2.class]§ Kör sen programmet med: - OSX/Linux: §java -classpath cmu_time_awb.jar:cmu_us_kal.jar:cmudict04.jar:cmulex.jar:cmutimelex.jar:en_us.jar:freetts.jar:jsapi.jar:. Client § - Windows: §java -classpath cmu_time_awb.jar;cmu_us_kal.jar;cmudict04.jar;cmulex.jar;cmutimelex.jar;en_us.jar;freetts.jar;jsapi.jar;. Client § Om man inte anger §host§ och/eller §port§ så kopplar sig chat-klienten till: - Host: §atlas.dsv.su.se§ - Port: §9494§ Använd gärna även talförståelse (speech-to-text). Ett enkelt exempel utan GUI kan köras enligt följande: = Hämta filen: §[ClientReceiver.class, 05_ass/ip1/2/2.1.1/terminal_version/ClientReceiver.class]§ = Hämta filen: §[ClientSender.class, 05_ass/ip1/2/2.1.1/terminal_version/ClientSender.class]§ = Kör programmet i terminalfönster 1 med: §java ClientReceiver§ = Kör programmet i terminalfönster 2 med: §java ClientSender§ Vi har här delat upp programmet i två delar eftersom det annars kan uppstå krockar i terminalfönstret när man samtidigt: - Skriver meddelanden - Tar emot meddelanden Exempelvis så kanske man börjar skriva på ett meddelande och mitt i det så kommer det in ett meddelande från någon annan och texten blandas eller kommer på en ny rad osv. __ Tips För att testa klienten måste man koppla den till en chattserver. Man kan antingen: - Hämta en chattserver och köra den på den egna datorn: -- Hämta filen §[Server.jar, 05_ass/ip1/2/2.1.2/Server.jar]§ -- Starta programmet med §java -jar Server.jar§ som startar chattservern på port §2000§ men man kan även ange ett annat portnummer som ett tredje argument, exempelvis §java -jar Server.jar 2001§ - Använda en chattserver på en annan dator: -- Host: §atlas.dsv.su.se§ -- Port: §9494§ Använd klassen §Socket§ och metoderna §getInputStream§ och §getOutputStream§ för att få strömmar att läsa och skriva från. Exempel på lämpliga ström-kopplingar: § in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(socket.getOutputStream(), true); § Notera att §PrintWriter§ default kan ha olika teckenmängder på olika plattformar så för att vara säker på att samma teckenmängd används bör man skriva: § out = new PrintWriter(new OutputStreamWriter(s.getOutputStream(), "ISO-8859-1"), true); § Klienten bör vara multitrådad. Hämtningen av meddelanden från servern bör ligga i en evig loop i metoden §run§. När man stänger klienten så kan programmet låsa sig, testa då med att stänga out-strömmen före in-strömmen. Chattservern implementerar ett minimalt protkoll som man kan leka med. Om en chattklient skickar §wwhhoo§ så returnerar chattservern alla uppkopplade chattklienters IP-adresser (den inleder svaret med §WWHHOO:§ för varje chattklient). Som överkurs kan man även titta på paketet §java.nio§, exempelvis på klassen §SocketChannel§. Lite tips for talsyntes: - Eftersom Java Speech API är en standard extension så måste man givetvis använda en mängd jar- och class-filer (med mera). - För att användaren ska slippa använda filen §speech.properties§ i användarens root-katalog (som man måste göra i [HelloWorld1.java, 05_ass/ip1/2/2.1.1/speech/examples/HelloWorld1.java]) så kan man göra enligt [HelloWorld2.java, 05_ass/ip1/2/2.1.1/speech/examples/HelloWorld2.java]. Man kan även använda talsyntes i andra uppgifter, exempelvis: - En webbläsare som läser upp texten i HTML-sidor - En epostklient som läser upp ebrev och även meddelar användaren när man får nya brev (med avsändare och ärende) Sånt är kul! :-) Se vidare: - [Oracle: Java Speech Programmer's Guide, 05_ass/ip1/2/2.1.1/speech/jsapi-guide.pdf] - [Oracle: Java Speech API 1.0, http://download.oracle.com/docs/cd/E17802_01/products/products/java-media/speech/forDevelopers/jsapi-doc/] __ Hjälp ~ 05_ass/help/01.txt > [Klicka här för hjälp, helper.dsv@gmail.com, Prog Internet: 2.1.1 Stream sockets på klientsidan: http://people.dsv.su.se/~pierre/i/i.cgi?href=05_ass/ip1/2.1.1.txt] ½===system_tutoring_message===½ < ~ 05_ass/help/02.txt