_ 2.2.2 Datagram sockets med multicast Vi ska nu fortsätta med en specifik variant av datagram sockets som kallas för multicastsocket och som används vid kommunikation en-till-flera: - Unicast: En till en (via TCP eller UDP) - Multicast: En till flera (via UDP) - Broadcast: en till alla (via UDP) Multicast är bra om man exempelvis vill sända ut en film till flera tittare: - Fördel: Man behöver bara sända ut en film oberoende av antalet tittare - Nackdel: Filmen måste sändas en viss tid Vi ska även använda ett egendefinierat applikationsnivåprotokoll. __ Uppgift Gör ett program som: = Sänder upprepade textmeddelanden på en multicast-IP-adress som enbart berättar att man är uppkopplad = Tar emot textmeddelanden från en multicast-IP-adress som visar vilka som är uppkopplade nu Textmeddelanden som sänds ska sändas 1 gång per sekund och vara formaterade enligt ett egetkonstruerat protokoll, vi kallar det OTTP, för Online Text Transfer Protocol :-): § From: Host: Comment: § Här är: - §§ anger namnet på användaren - §§ anger användarens host - §§ anger en kommentar från användaren Det är viktigt att man inte sänder meddelandena oftare än 1 gång per sekund då det i UDP inte finns någon inbyggd trafikövervakning. Sänder man med UDP för ofta kan nätverket bli överbelastat och gå ner. Textmeddelanden som tas emot ska parsas och för varje namn/host kombination så ska informationen visas på följande format så länge denna användare är uppkopplad: § name --- host --- comment § Endast en rad för varje användare ska visas. Om programmet tar emot ett meddelanden som inte följer OTTP-protokollet så ska det skriva ut §COULD NOT PARSE MESSAGE§ i textarean. Programmet ska koppla sig till multicastadressen §234.235.236.237§ på port §2000§. Om kopplingen lyckas så ska det i programmets titelrad stå vilken IP-adress och port uppkopplingen skett till. Om kopplingen inte lyckas så ska programmet avslutas. __ Exempel Ett enkelt exempel kan köras enligt följande (om man har stöd för multicast-routing, se nedan under Tips): = Hämta filen: §[OnLine.jar, 05_ass/ip1/2/2.2.2/OnLine.jar]§ = Kör igång programmet med: §java -jar OnLine.jar § Ett enkelt exempel utan GUI kan köras enligt följande (om man har stöd för multicast-routing, se nedan under Tips): = Hämta filen: §[OnLine.jar, 05_ass/ip1/2/2.2.2/terminal_version/OnLineTerm.jar]§ = Kör igång programmet med: §java -jar OnLine.jar § Kör gärna igång flera program på flera olika datorer. Tänk dock på att multicast är en teknik som för nuvarande fungerar bäst i intranät. __ Tips Använd exempelvis fyra klasser: - En klass §OnLine§ för det grafiska gränssnittet och initialiseringen av §MulticastSocket§ - En inre trådad klass §Sender§ för kontinuerlig sändning av §DatagramPacket§ meddelanden en gång per sekund - En inre trådad klass §Receiver§ för kontinuerlig mottagning av §DatagramPacket§ meddelanden där mottagna meddelanden (det vill säga texten) läggs i en datasamling (exempelvis ett §HashSet§) om de inte finns i datasamlingen tidigare - En inre trådad klass §InterfaceHandler§ för kontinuerlig uppdatering av gränssnittet var 5:e sekund: -- Töm textarean -- Parsa de meddelanden som finns i datasamlingen och lägg in resultaten i textarean -- Töm datasamlingen Har man implementerat detta med flera trådar som möjligtvis delar på någon resurs så kan krockar uppstå och man bör således deklarera vissa metoder som §synchronized§ och/eller använda de synkroniserade datasamlingarna. I exemplet har dock inget av detta använts. För att dela upp ett inkommet meddelande i enstaka ord så är klassen §java.util.StringTokenizer§ utmärkt. Notera att: - §multicastSocket.getInetAddress()§ ger värdet §null§ - §multicastSocket.getLocalPort()§ ger värdet §-1§ och att det är bättre att använda: - §InetAddress.getLocalHost().getHostAddress()§ - §multicastSocket.getPort()§ Man måste skapa ett nytt §DatagramPacket§ för varje meddelande som ska tas emot. Man måste ha stöd för multicast-routing i sin dator eller hos den ISP som man kopplar upp sig mot. Detta kan testas med: § ping all-routers.mcast.net § Får man svaret: § all-routers.mcast.net is alive § så har man stöd. Annars så måste man konfigurera sin dator så att man får stöd. Om man har konfigurerat sin dator för multicast så betyder det tyvärr inte att man kan använda multicast utanför datorn eftersom många ISP:er inte använder multicast. Då kan man således bara använda sina multicastprogram lokalt, vilket givetvis är trist. En lösning till det är att använda ett tunnelprogram till en dator som använder multicast och helst är ansluten till MBone som är ett nätverk av routrar som stöder multicast. Med ett tunnelprogram så kan man alltså använda multicast även utanför sin egen dator. Om den dator som tunnelservern kör på inte är ansluten till MBone så kräver det dock att alla klienter som vill kommunicera via mulitcast använder en tunnel till samma tunnelserver och då är vi ju tillbaka till vanlig unicastkommunikation. Det bästa är givetvis om den dator som tunnelservern kör på är ansluten till MBone, då behöver inte alla klienter använda samma tunnelserver och det blir mer likt verklig multicast. På §atlas.dsv.su.se§ kör nu en tunnelserver för multicast som man kan ansluta till genom: - Hämta filen: §[Client.jar, 05_ass/ip1/2/2.2.2/tunnel/Client.jar]§ - Kör med: §java -jar Client.jar § Kör man utan argument så används: - Multicast-adress: §234.235.236.237§ - Multicast-port: §2000§ - TTL: §1§ Tyvärr så är inte atlas eller andra datorer på DSV anslutna till MBone (men det kanske kommer senare), något som kan testas med: - Hämta filen: §[MBone.class, 05_ass/ip1/2/2.2.2/mbone/MBone.class]§ - Kör med: §java MBone § Kör man utan argument så används: - Multicast-adress: §all-systems.mcast.net§ - Multicast-port: §4000§ - TTL: §1§ Händer det inget så är man inte ansluten till MBone. Men man kan ändå simulera en multicastuppkoppling mellan flera datorer om alla datorer använder tunnelprogrammet ovan. Tunnelklienten och tunnelservern är gjord helt i Java och fungerar så här: - Tunnelservern: -- Från MBone till tunnelklienten: --- Ta emot multicastmeddelanden från MBone på en multicast socket --- Sänd alla mottagna meddelanden till tunnelklienten via en datagram socket -- Från tunnelklienten till MBone: --- Ta emot datagrammeddelanden från tunnelklienten på en datagram socket --- Sänd alla mottagna meddelanden till MBone på en multicast socket - Tunnelklienten: -- Från program hos klienten till tunnelservern: --- Ta emot multicastmeddelanden från andra program hos klienten på en multicast socket --- Sänd alla mottagna meddelanden till tunnelservern via en datagram socket -- Från tunnelservern till program hos klienten: --- Ta emot datagrammeddelanden från tunnelservern på en datagram socket --- Sänd alla mottagna meddelanden till program hos klienten på en multicast socket Klienten och servern använder även stream sockets för sessionshanteringen. __ Hjälp ~ 05_ass/help/01.txt > [Klicka här för hjälp, helper.dsv@gmail.com, IP Stationär: 2.2.2 Datagram sockets med multicast: http://people.dsv.su.se/~pierre/i/i.cgi?href=05_ass/ip1/2.2.2.txt] < ~ 05_ass/help/02.txt