Hur man skapar ett nätverksprogram i Java (med bilder)

Innehållsförteckning:

Hur man skapar ett nätverksprogram i Java (med bilder)
Hur man skapar ett nätverksprogram i Java (med bilder)

Video: Hur man skapar ett nätverksprogram i Java (med bilder)

Video: Hur man skapar ett nätverksprogram i Java (med bilder)
Video: OND FRÅN UNDERJORDEN TORLERAR FAMILJEN I ÅR I DETTA HUSET 2024, Maj
Anonim

Att skriva kod som körs på en viss enhet är mycket tillfredsställande. Men att skriva kod som körs på flera enheter som kommunicerar med varandra är helt enkelt livsbekräftande. Den här artikeln kommer att lära dig hur du ansluter och utbyter meddelanden över nätverk med hjälp av överföringskontrollprotokoll (TCP).

I den här artikeln kommer du att konfigurera ett program som ansluter din dator till sig själv och i huvudsak gör det galet - prata med sig själv. Du kommer också att lära dig skillnaden mellan de två mest använda strömmarna för nätverk i Java och hur de fungerar.

Data- och objektströmmar

Innan du dyker ner i kod måste skillnaden mellan de två strömmar som används i artikeln särskiljas.

Dataströmmar

Dataströmmar behandlar primitiva datatyper och strängar. Data som skickas över dataströmmar måste seriellt och deserialiseras manuellt vilket gör det svårare att överföra komplexa data. Men dataströmmar kan kommunicera med servrar och klienter skrivna på andra språk än Java. Raw streams liknar dataströmmar i den aspekten, men dataströmmar säkerställer att data formateras på ett plattformsoberoende sätt vilket är fördelaktigt eftersom båda parter kommer att kunna läsa skickad data.

Objektströmmar

Objektströmmar bearbetar primitiva datatyper och objekt som implementerar

Serialiserbar

gränssnitt. Data som skickas över objektströmmar serialiseras och avserialiseras automatiskt vilket gör det lättare att överföra komplexa data. Men objektströmmar kan bara kommunicera med servrar och klienter skrivna i Java. Också,

ObjectOutputStream

vid initialisering skickar ett rubrik till

InputStream

från den andra parten som vid initialisering blockerar körning tills rubriken tas emot.

Steg

Skapa ett nätverksprogram i Java Step1
Skapa ett nätverksprogram i Java Step1

Steg 1. Skapa en klass

Skapa en klass och namnge den hur du vill. I den här artikeln kommer den att namnges

NetworkAppExample

public class NetworkAppExample {}

Skapa ett nätverksprogram i Java Step2
Skapa ett nätverksprogram i Java Step2

Steg 2. Skapa en huvudmetod

Skapa en huvudmetod och förklara att den kan ge undantag från

Undantag

typ och eventuell underklass - alla undantag. Detta anses vara en dålig praxis, men är acceptabelt för barebone -exempel.

public class NetworkAppExample {public static void main (String args) kastar undantag {}}

Skapa ett nätverksprogram i Java Step3
Skapa ett nätverksprogram i Java Step3

Steg 3. Deklarera serveradress

I det här exemplet används lokal värdadress och ett godtyckligt portnummer. Portnummer måste ligga i intervallet från 0 till 65535 (inklusive). Portnumren som ska undvikas varierar emellertid från 0 till 1023 (inklusive) eftersom de är reserverade systemportar.

public class NetworkAppExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; }}

Skapa ett nätverksprogram i Java Step4
Skapa ett nätverksprogram i Java Step4

Steg 4. Skapa en server

Servern är bunden till adressen och porten och lyssnar efter inkommande anslutningar. I Java,

ServerSocket

representerar serversidan slutpunkt och dess funktion är att acceptera nya anslutningar.

ServerSocket

har inte strömmar för att läsa och skicka data eftersom det inte representerar anslutningen mellan en server och en klient.

importera java.net. InetAddress; importera java.net. ServerSocket; public class NetworkAppExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; ServerSocket -server = ny ServerSocket (port, 50, InetAddress.getByName (värd)); }}

Skapa ett nätverksprogram i Java Step5
Skapa ett nätverksprogram i Java Step5

Steg 5. Start av loggserver

För loggning, skriv ut till konsolen att servern har startats.

importera java.net. InetAddress; importera java.net. ServerSocket; public class NetworkAppExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; ServerSocket -server = ny ServerSocket (port, 50, InetAddress.getByName (värd)); System.out.println ("Server startad."); }}

Skapa ett nätverksprogram i Java Step6
Skapa ett nätverksprogram i Java Step6

Steg 6. Skapa en klient

Klienten är bunden till adressen och porten på en server och lyssnar efter paket (meddelanden) efter att anslutningen upprättats. I Java,

Uttag

representerar antingen en slutpunkt på klientsidan som är ansluten till servern eller en anslutning (från server) till klient och används för att kommunicera med parten i andra änden.

importera java.net. InetAddress; importera java.net. ServerSocket; importera java.net. Socket; public class NetworkAppExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; ServerSocket -server = ny ServerSocket (port, 50, InetAddress.getByName (värd)); System.out.println ("Server startad."); Socket -klient = ny Socket (värd, port); }}

Skapa ett nätverksprogram i Java Step7
Skapa ett nätverksprogram i Java Step7

Steg 7. Logganslutningsförsök

För loggning, skriv ut till konsolen att anslutningen har försökt.

importera java.net. InetAddress; importera java.net. ServerSocket; importera java.net. Socket; public class NetworkAppExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; ServerSocket -server = ny ServerSocket (port, 50, InetAddress.getByName (värd)); System.out.println ("Server startad."); Socket -klient = ny Socket (värd, port); System.out.println ("Ansluter till server …"); }}

Skapa ett nätverksprogram i Java Step8
Skapa ett nätverksprogram i Java Step8

Steg 8. Upprätta anslutning

Klienter kommer aldrig att ansluta om inte servern lyssnar efter och accepterar, med andra ord upprättar, anslutningar. I Java upprättas anslutningar med

acceptera()

metod av

ServerSocket

klass. Metoden blockerar körningen tills en klient ansluter.

importera java.net. InetAddress; importera java.net. ServerSocket; importera java.net. Socket; public class NetworkAppExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; ServerSocket -server = ny ServerSocket (port, 50, InetAddress.getByName (värd)); System.out.println ("Server startad."); Socket -klient = ny Socket (värd, port); System.out.println ("Ansluter till server …"); Socket -anslutning = server.accept (); }}

Skapa ett nätverksprogram i Java Step9
Skapa ett nätverksprogram i Java Step9

Steg 9. Logga upprättad anslutning

För loggning, skriv ut till konsolen att anslutningen mellan server och klient har upprättats.

importera java.net. InetAddress; importera java.net. ServerSocket; importera java.net. Socket; public class NetworkAppExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; ServerSocket -server = ny ServerSocket (port, 50, InetAddress.getByName (värd)); System.out.println ("Server startad."); Socket -klient = ny Socket (värd, port); System.out.println ("Ansluter till server …"); Socket -anslutning = server.accept (); System.out.println ("Anslutning upprättad."); }}

Skapa ett nätverksprogram i Java Step10
Skapa ett nätverksprogram i Java Step10

Steg 10. Förbered kommunikationsströmmar

Kommunikation sker via strömmar och i denna applikation måste råa strömmar från (anslutning från) server (till klient) och klient kopplas till antingen data- eller objektströmmar. Kom ihåg att båda parter måste använda samma strömtyp.

  • Dataströmmar

    importera java.io. DataInputStream; importera java.io. DataOutputStream; importera java.net. InetAddress; importera java.net. ServerSocket; importera java.net. Socket; public class NetworkAppExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; ServerSocket -server = ny ServerSocket (port, 50, InetAddress.getByName (värd)); System.out.println ("Server startad."); Socket -klient = ny Socket (värd, port); System.out.println ("Ansluter till server …"); Socket -anslutning = server.accept (); System.out.println ("Anslutning upprättad."); DataOutputStream clientOut = ny DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = ny DataInputStream (client.getInputStream ()); DataOutputStream serverOut = ny DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = ny DataInputStream (connection.getInputStream ()); }}

  • Objektströmmar

    När flera objektströmmar används måste inmatningsströmmar initieras i samma ordning som utdataströmmar eftersom

    ObjectOutputStream

    skickar en rubrik till den andra parten och

    ObjectInputStream

    blockerar körning tills den läser rubriken.

    importera java.io. ObjectInputStream; importera java.io. ObjectOutputStream; importera java.net. InetAddress; importera java.net. ServerSocket; importera java.net. Socket; public class NetworkAppExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; ServerSocket -server = ny ServerSocket (port, 50, InetAddress.getByName (värd)); System.out.println ("Server startad."); Socket -klient = ny Socket (värd, port); System.out.println ("Ansluter till server …"); Socket -anslutning = server.accept (); System.out.println ("Anslutning upprättad."); ObjectOutputStream clientOut = nytt ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nytt ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nytt ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nytt ObjectInputStream (connection.getInputStream ()); }}

    Ordning som anges i koden ovan kan vara lättare att komma ihåg - initiera först utflöden och sedan inmatningsströmmar i samma ordning. En annan order för initialisering av objektströmmar är dock följande:

    ObjectOutputStream clientOut = nytt ObjectOutputStream (client.getOutputStream ()); ObjectInputStream serverIn = nytt ObjectInputStream (connection.getInputStream ()); ObjectOutputStream serverOut = nytt ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nytt ObjectInputStream (client.getInputStream ());

Skapa ett nätverksprogram i Java Step11
Skapa ett nätverksprogram i Java Step11

Steg 11. Logga in att kommunikationen är klar

För loggning, skriv ut till konsolen att kommunikationen är klar.

// kod utelämnad import java.net. InetAddress; importera java.net. ServerSocket; importera java.net. Socket; public class NetworkAppExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; ServerSocket -server = ny ServerSocket (port, 50, InetAddress.getByName (värd)); System.out.println ("Server startad."); Socket -klient = ny Socket (värd, port); System.out.println ("Ansluter till server …"); Socket -anslutning = server.accept (); System.out.println ("Anslutning upprättad."); // kod utelämnad System.out.println ("Kommunikationen är klar."); }}

Skapa ett nätverksprogram i Java Step12
Skapa ett nätverksprogram i Java Step12

Steg 12. Skapa ett meddelande

I denna ansökan,

Hej världen

text skickas till servern antingen som

byte

eller

Sträng

. Deklarera en variabel av typen som beror på vilken ström som används. Använda sig av

byte

för dataströmmar och

Sträng

för objektströmmar.

  • Dataströmmar

    Med hjälp av dataströmmar görs serialisering genom att omvandla objekt till primitiva datatyper eller a

    Sträng

    . I detta fall,

    Sträng

    konverteras till

    byte

    istället för att skriva med

    writeBytes ()

    metod för att visa hur det skulle göras med andra objekt, till exempel bilder eller andra filer.

    importera java.io. DataInputStream; importera java.io. DataOutputStream; importera java.net. InetAddress; importera java.net. ServerSocket; importera java.net. Socket; public class NetworkAppExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; ServerSocket -server = ny ServerSocket (port, 50, InetAddress.getByName (värd)); System.out.println ("Server startad."); Socket -klient = ny Socket (värd, port); System.out.println ("Ansluter till server …"); Socket -anslutning = server.accept (); System.out.println ("Anslutning upprättad."); DataOutputStream clientOut = ny DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = ny DataInputStream (client.getInputStream ()); DataOutputStream serverOut = ny DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = ny DataInputStream (connection.getInputStream ()); System.out.println ("Kommunikationen är klar."); byte messageOut = "Hej världen".getBytes (); }}

  • Objektströmmar

    importera java.io. ObjectInputStream; importera java.io. ObjectOutputStream; importera java.net. InetAddress; importera java.net. ServerSocket; importera java.net. Socket; public class NetworkAppExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; ServerSocket -server = ny ServerSocket (port, 50, InetAddress.getByName (värd)); System.out.println ("Server startad."); Socket -klient = ny Socket (värd, port); System.out.println ("Ansluter till server …"); Socket -anslutning = server.accept (); System.out.println ("Anslutning upprättad."); ObjectOutputStream clientOut = nytt ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nytt ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nytt ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nytt ObjectInputStream (connection.getInputStream ()); System.out.println ("Kommunikationen är klar."); String messageOut = "Hej världen"; }}

Skapa ett nätverksprogram i Java Step13
Skapa ett nätverksprogram i Java Step13

Steg 13. Skicka meddelandet

Skriv data till utmatningsströmmen och spola strömmen för att säkerställa att data har skrivits helt.

  • Dataströmmar

    Ett meddelandes längd måste skickas först så att den andra parten vet hur många byte det behöver läsa. Efter att längden har skickats som en primitiv heltalstyp kan byte skickas.

    importera java.io. DataInputStream; importera java.io. DataOutputStream; importera java.net. InetAddress; importera java.net. ServerSocket; importera java.net. Socket; public class NetworkAppExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; ServerSocket -server = ny ServerSocket (port, 50, InetAddress.getByName (värd)); System.out.println ("Server startad."); Socket -klient = ny Socket (värd, port); System.out.println ("Ansluter till server …"); Socket -anslutning = server.accept (); System.out.println ("Anslutning upprättad."); DataOutputStream clientOut = ny DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = ny DataInputStream (client.getInputStream ()); DataOutputStream serverOut = ny DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = ny DataInputStream (connection.getInputStream ()); System.out.println ("Kommunikationen är klar."); byte messageOut = "Hej världen".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); }}

  • Objektströmmar

    importera java.io. ObjectInputStream; importera java.io. ObjectOutputStream; importera java.net. InetAddress; importera java.net. ServerSocket; importera java.net. Socket; public class NetworkAppExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; ServerSocket -server = ny ServerSocket (port, 50, InetAddress.getByName (värd)); System.out.println ("Server startad."); Socket -klient = ny Socket (värd, port); System.out.println ("Ansluter till server …"); Socket -anslutning = server.accept (); System.out.println ("Anslutning upprättad."); ObjectOutputStream clientOut = nytt ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nytt ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nytt ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nytt ObjectInputStream (connection.getInputStream ()); System.out.println ("Kommunikationen är klar."); String messageOut = "Hej världen"; clientOut.writeObject (messageOut); clientOut.flush (); }}

Skapa ett nätverksprogram i Java Step14
Skapa ett nätverksprogram i Java Step14

Steg 14. Loggskickat meddelande

För loggning, skriv ut till konsolen att meddelandet har skickats.

  • Dataströmmar

    importera java.io. DataInputStream; importera java.io. DataOutputStream; importera java.net. InetAddress; importera java.net. ServerSocket; importera java.net. Socket; public class NetworkAppExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; ServerSocket -server = ny ServerSocket (port, 50, InetAddress.getByName (värd)); System.out.println ("Server startad."); Socket -klient = ny Socket (värd, port); System.out.println ("Ansluter till server …"); Socket -anslutning = server.accept (); System.out.println ("Anslutning upprättad."); DataOutputStream clientOut = ny DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = ny DataInputStream (client.getInputStream ()); DataOutputStream serverOut = ny DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = ny DataInputStream (connection.getInputStream ()); System.out.println ("Kommunikationen är klar."); byte messageOut = "Hello World".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Meddelande skickat till servern:" + ny sträng (messageOut)); }}

  • Objektströmmar

    importera java.io. ObjectInputStream; importera java.io. ObjectOutputStream; importera java.net. InetAddress; importera java.net. ServerSocket; importera java.net. Socket; public class NetworkAppExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; ServerSocket -server = ny ServerSocket (port, 50, InetAddress.getByName (värd)); System.out.println ("Server startad."); Socket -klient = ny Socket (värd, port); System.out.println ("Ansluter till server …"); Socket -anslutning = server.accept (); System.out.println ("Anslutning upprättad."); ObjectOutputStream clientOut = nytt ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nytt ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nytt ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nytt ObjectInputStream (connection.getInputStream ()); System.out.println ("Kommunikationen är klar."); String messageOut = "Hej världen"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Meddelande skickat till servern:" + messageOut); }}

Skapa ett nätverksprogram i Java Step15
Skapa ett nätverksprogram i Java Step15

Steg 15. Läs meddelandet

Läs data från inmatningsströmmen och konvertera den. Eftersom vi vet exakt vilken typ av skickad data, kommer vi antingen att skapa en

Sträng

från

byte

eller gjutna

Objekt

till

Sträng

utan att kontrollera, beroende på vilken ström som används.

  • Dataströmmar

    Eftersom längden skickades först och byte efteråt måste avläsningen göras i samma ordning. Om längden är noll finns det inget att läsa. Objekt avserialiseras när byte konverteras tillbaka till en instans, i det här fallet, av

    Sträng

    importera java.io. DataInputStream; importera java.io. DataOutputStream; importera java.net. InetAddress; importera java.net. ServerSocket; importera java.net. Socket; public class NetworkAppExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; ServerSocket -server = ny ServerSocket (port, 50, InetAddress.getByName (värd)); System.out.println ("Server startad."); Socket -klient = ny Socket (värd, port); System.out.println ("Ansluter till server …"); Socket -anslutning = server.accept (); System.out.println ("Anslutning upprättad."); DataOutputStream clientOut = ny DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = ny DataInputStream (client.getInputStream ()); DataOutputStream serverOut = ny DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = ny DataInputStream (connection.getInputStream ()); System.out.println ("Kommunikationen är klar."); byte messageOut = "Hello World".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Meddelande skickat till servern:" + ny sträng (messageOut)); int length = serverIn.readInt (); if (längd> 0) {byte meddelandeIn = ny byte [längd]; serverIn.readFully (messageIn, 0, messageIn.length); }}}

  • Objektströmmar

    importera java.io. ObjectInputStream; importera java.io. ObjectOutputStream; importera java.net. InetAddress; importera java.net. ServerSocket; importera java.net. Socket; public class NetworkAppExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; ServerSocket -server = ny ServerSocket (port, 50, InetAddress.getByName (värd)); System.out.println ("Server startad."); Socket -klient = ny Socket (värd, port); System.out.println ("Ansluter till server …"); Socket -anslutning = server.accept (); System.out.println ("Anslutning upprättad."); ObjectOutputStream clientOut = nytt ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nytt ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nytt ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nytt ObjectInputStream (connection.getInputStream ()); System.out.println ("Kommunikationen är klar."); String messageOut = "Hej världen"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Meddelande skickat till servern:" + messageOut); String messageIn = (String) serverIn.readObject (); }}

Skapa ett nätverksprogram i Java Step16
Skapa ett nätverksprogram i Java Step16

Steg 16. Logga läsmeddelande

För loggning, skriv ut till konsolen att meddelandet har mottagits och skriv ut dess innehåll.

  • Dataströmmar

    importera java.io. DataInputStream; importera java.io. DataOutputStream; importera java.net. InetAddress; importera java.net. ServerSocket; importera java.net. Socket; public class NetworkAppExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; ServerSocket -server = ny ServerSocket (port, 50, InetAddress.getByName (värd)); System.out.println ("Server startad."); Socket -klient = ny Socket (värd, port); System.out.println ("Ansluter till server …"); Socket -anslutning = server.accept (); System.out.println ("Anslutning upprättad."); DataOutputStream clientOut = ny DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = ny DataInputStream (client.getInputStream ()); DataOutputStream serverOut = ny DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = ny DataInputStream (connection.getInputStream ()); System.out.println ("Kommunikationen är klar."); byte messageOut = "Hello World".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Meddelande skickat till servern:" + ny sträng (messageOut)); int length = serverIn.readInt (); if (längd> 0) {byte meddelandeIn = ny byte [längd]; serverIn.readFully (messageIn, 0, messageIn.length); System.out.println ("Meddelande mottaget från klient:" + ny sträng (messageIn)); }}}

  • Objektströmmar

    importera java.io. ObjectInputStream; importera java.io. ObjectOutputStream; importera java.net. InetAddress; importera java.net. ServerSocket; importera java.net. Socket; public class NetworkAppExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; ServerSocket -server = ny ServerSocket (port, 50, InetAddress.getByName (värd)); System.out.println ("Server startad."); Socket -klient = ny Socket (värd, port); System.out.println ("Ansluter till server …"); Socket -anslutning = server.accept (); System.out.println ("Anslutning upprättad."); ObjectOutputStream clientOut = nytt ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = nytt ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = nytt ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = nytt ObjectInputStream (connection.getInputStream ()); System.out.println ("Kommunikationen är klar."); String messageOut = "Hej världen"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Meddelande skickat till servern:" + messageOut); String messageIn = (String) serverIn.readObject (); System.out.println ("Meddelande mottaget från klient:" + messageIn); }}

Skapa ett nätverksprogram i Java Step17
Skapa ett nätverksprogram i Java Step17

Steg 17. Koppla bort anslutningarna

Anslutningen kopplas bort när en part stänger sina strömmar. I Java stängs också tillhörande uttag och ingångsström genom att stänga utströmmen. När en part i andra änden upptäcker att anslutningen är död, måste den också stänga sin utström för att förhindra minnesläckage.

// kod utelämnad import java.net. InetAddress; importera java.net. ServerSocket; importera java.net. Socket; public class NetworkAppExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; ServerSocket -server = ny ServerSocket (port, 50, InetAddress.getByName (värd)); System.out.println ("Server startad."); Socket -klient = ny Socket (värd, port); System.out.println ("Ansluter till server …"); Socket -anslutning = server.accept (); System.out.println ("Anslutning upprättad."); // kod utelämnad System.out.println ("Kommunikationen är klar."); // kod utelämnad clientOut.close (); serverOut.close (); }}

Skapa ett nätverksprogram i Java Step18 V2
Skapa ett nätverksprogram i Java Step18 V2

Steg 18. Loggkoppling

För loggning har anslutningarna för utskrift till konsolen kopplats bort.

// kod utelämnad import java.net. InetAddress; importera java.net. ServerSocket; importera java.net. Socket; public class NetworkAppExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; ServerSocket -server = ny ServerSocket (port, 50, InetAddress.getByName (värd)); System.out.println ("Server startad."); Socket -klient = ny Socket (värd, port); System.out.println ("Ansluter till server …"); Socket -anslutning = server.accept (); System.out.println ("Anslutning upprättad."); // kod utelämnad System.out.println ("Kommunikationen är klar."); // kod utelämnad clientOut.close (); serverOut.close (); System.out.println ("Anslutningar stängda."); }}

Skapa ett nätverksprogram i Java Step19
Skapa ett nätverksprogram i Java Step19

Steg 19. Avsluta servern

Anslutningarna är frånkopplade, men servern är fortfarande igång. Som

ServerSocket

är inte associerad med någon ström, måste det uttryckligen stängas genom att ringa

stänga()

metod.

// kod utelämnad import java.net. InetAddress; importera java.net. ServerSocket; importera java.net. Socket; public class NetworkAppExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; ServerSocket -server = ny ServerSocket (port, 50, InetAddress.getByName (värd)); System.out.println ("Server startad."); Socket -klient = ny Socket (värd, port); System.out.println ("Ansluter till server …"); Socket -anslutning = server.accept (); System.out.println ("Anslutning upprättad."); // kod utelämnad System.out.println ("Kommunikationen är klar."); // kod utelämnad clientOut.close (); serverOut.close (); System.out.println ("Anslutningar stängda."); server.close (); }}

Skapa ett nätverksprogram i Java Step20
Skapa ett nätverksprogram i Java Step20

Steg 20. Avslutning av loggserver

För loggning har utskriften till konsolservern avslutats.

// kod utelämnad import java.net. InetAddress; importera java.net. ServerSocket; importera java.net. Socket; public class NetworkAppExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; ServerSocket -server = ny ServerSocket (port, 50, InetAddress.getByName (värd)); System.out.println ("Server startad."); Socket -klient = ny Socket (värd, port); System.out.println ("Ansluter till server …"); Socket -anslutning = server.accept (); System.out.println ("Anslutning upprättad."); // kod utelämnad System.out.println ("Kommunikationen är klar."); // kod utelämnad clientOut.close (); serverOut.close (); System.out.println ("Anslutningar stängda."); server.close (); System.out.println ("Server avslutad."); }}

Skapa ett nätverksprogram i Java Step21
Skapa ett nätverksprogram i Java Step21

Steg 21. Kompilera och kör

Loggning gjorde det möjligt för oss att veta om programmet lyckades eller inte. Förväntad produktion:

Servern startade. Ansluter till server … Anslutning upprättad. Kommunikationen är klar. Meddelande skickat till servern: Hello World Meddelande mottaget från klienten: Hello World Connections stängda. Servern har avslutats.

Om din utmatning inte är som den ovan, vilket osannolikt kommer att hända, finns det några lösningar:

  • Om utgången stannar vid linjen

    Kontakt etablerad.

    och objektströmmar används, spola var och en

    ObjectOutputStream

  • omedelbart efter initialiseringen eftersom rubriker av någon anledning inte skickades.
  • Om utskriften skrivs ut

    java.net. BindException: Adress som redan används

  • välj ett annat portnummer eftersom det angivna redan används.

Tips

  • Anslutning till en server i ett annat nätverk görs genom att ansluta till den externa IP -adressen för en enhet som kör servern som har en vidarebefordrad port.
  • Anslutning till en server i samma nätverk görs genom att antingen ansluta till den privata IP -adressen för en enhet som kör servern eller vidarebefordra en port och ansluta till enhetens externa IP -adress.
  • Det finns programvara, till exempel Hamachi, som gör det möjligt att ansluta till servern i ett annat nätverk utan att vidarebefordra en port, men det kräver installation av programvaran på båda enheterna.

Exempel

Nätverksapplikationer som använder blockerande input/output måste använda trådar. Följande exempel visar en minimalistisk server- och klientimplementering med trådar. Nätverkskoden är i huvudsak densamma som i artikeln förutom att några utdrag synkroniserades, flyttades till trådar och undantag hanteras.

Server.java

importera java.io. IOException; importera java.net. InetAddress; importera java.net. ServerSocket; importera java.net. SocketException; importera java.net. UnknownHostException; importera java.util. ArrayList; importera java.util. Collections; importera java.util. List; /*** Klassen {@code Server} representerar en server slutpunkt i ett nätverk. {@code Server} en gång bunden till en viss IP * -adress och port, upprättar anslutningar med klienter och kan kommunicera med dem eller koppla bort dem. *

* Den här klassen är trådsäker. * * @version 1.0 * @see Client * @see Connection */ public class Server implementerar Runnable {private ServerSocket server; privat lista anslutningar; privat trådtråd; private final Object connectionsLock = new Object (); /** * Konstruerar en {@code Server} som interagerar med klienter på det angivna värdnamnet och porten med den angivna * begärda maximala längden på en kö av inkommande klienter. * * @param värd Värdadress som ska användas. * @param -port Portnummer som ska användas. * @param backlog Begärde maximal längd på kön för inkommande klienter. * @kastar NetworkException Om ett fel uppstår när en server startas. */ public Server (String host, int port, int backlog) kastar NetworkException {try {server = new ServerSocket (port, backlog, InetAddress.getByName (host)); } catch (UnknownHostException e) {throw new NetworkException ("Värdnamn kunde inte lösas:" + värd, e); } catch (IllegalArgumentException e) {throw new NetworkException ("Portnummer måste vara mellan 0 och 65535 (inklusive):" + port); } catch (IOException e) {throw new NetworkException ("Servern kunde inte startas.", e); } anslutningar = Collections.synchronizedList (ny ArrayList ()); tråd = ny tråd (detta); thread.start (); } /*** Konstruerar en {@code Server} som interagerar med klienter på det angivna värdnamnet och porten. * * @param värd Värdadress att binda. * @param -port Portnummer som ska bindas. * @throws NetworkException Om det uppstår fel när en server startas. */ public Server (String -värd, int -port) kastar NetworkException {detta (värd, port, 50); } /*** Lyssnar på, accepterar och registrerar inkommande anslutningar från klienter. */ @Override public void run () {while (! Server.isClosed ()) {try {connections.add (new Connection (server.accept ())); } catch (SocketException e) {if (! e.getMessage (). är lika med ("Socket stängd")) {e.printStackTrace (); }} catch (NetworkException | IOException e) {e.printStackTrace (); }}} /*** Skickar data till alla registrerade klienter. * * @param data Data att skicka. * @throws IllegalStateException Om du försöker skriva data när servern är offline. * @throws IllegalArgumentException Om data som ska skickas är noll. */ public void broadcast (Objektdata) {if (server.isClosed ()) {kasta ny IllegalStateException ("Data skickas inte, servern är offline."); } if (data == null) {kasta ny IllegalArgumentException ("null data"); } synkroniserad (connectionsLock) {för (Anslutningsanslutning: anslutningar) {prova {connection.send (data); System.out.println ("Data skickades till klienten framgångsrikt."); } catch (NetworkException e) {e.printStackTrace (); }}}} /*** Skickar ett frånkopplingsmeddelande och kopplar bort angiven klient. * * @param -anslutning Klienten kopplar bort. * @kastar NetworkException Om ett fel uppstår när anslutningen stängs. */ public void disconnect (Connection connection) kastar NetworkException {if (connections.remove (anslutning)) {connection.close (); }} /*** Skickar ett frånkopplingsmeddelande till alla klienter, kopplar bort dem och avslutar servern. */ public void close () kastar NetworkException {synchronized (connectionsLock) {för (Connection connection: connections) {try {connection.close (); } catch (NetworkException e) {e.printStackTrace (); }}} connections.clear (); prova {server.close (); } catch (IOException e) {kasta nytt NetworkException ("Fel vid stängning av server."); } äntligen {thread.interrupt (); }} /*** Returnerar om servern är online eller inte. * * @return True om servern är online. Falskt, annars. */ public boolean isOnline () {return! server.isClosed (); } /*** Returnerar en rad registrerade klienter. */ public Connection getConnections () {synchronized (connectionsLock) {return connections.toArray (new Connection [connections.size ()]); }}}

Client.java

importera java.io. IOException; importera java.net. Socket; importera java.net. UnknownHostException; /*** Klassen {@code Client} representerar en klients slutpunkt i ett nätverk. {@code Client}, när den väl är ansluten till en viss * server, kan garanterat bara kommunicera med servern. Om andra klienter får data * beror på serverimplementeringen. *

* Den här klassen är trådsäker. * * @version 1.0 * @see Server * @see Connection */ public class Client {privat anslutningsanslutning; /*** Konstruerar en {@code Client} som är ansluten till servern på den angivna värden och porten. * * @param värd Värdadress att binda. * @param -port Portnummer som ska bindas. * @kastar NetworkException Om ett fel uppstår när en server startas. */ public Client (String host, int port) kastar NetworkException {try {connection = new Connection (new Socket (host, port)); } catch (UnknownHostException e) {throw new NetworkException ("Värdnamn kunde inte lösas:" + värd, e); } catch (IllegalArgumentException e) {throw new NetworkException ("Portnummer måste vara mellan 0 och 65535 (inklusive):" + port); } catch (IOException e) {throw new NetworkException ("Servern kunde inte startas.", e); }} /*** Skickar data till den andra parten. * * @param data Data att skicka. * @kastar NetworkException Om skrivning till utdataström misslyckas. * @throws IllegalStateException Om du försöker skriva data när anslutningen stängs. * @throws IllegalArgumentException Om data som ska skickas är noll. * @throws UnsupportedOperationException Om datatyp som inte stöds ska skickas. */ public void send (objektdata) kastar NetworkException {connection.send (data); } /*** Skickar ett frånkopplingsmeddelande till och stänger anslutningen till servern. */ public void close () kastar NetworkException {connection.close (); } /*** Returnerar om klienten är ansluten till servern eller inte. * * @return True om klienten är ansluten. Falskt, annars. */ public boolean isOnline () {returanslutning.isConnected (); } /*** Returnerar instansen {@link Connection} för klienten. */ public Connection getConnection () {returanslutning; }}

Anslutning. Java

importera java.io. DataInputStream; importera java.io. DataOutputStream; importera java.io. IOException; importera java.net. Socket; importera java.net. SocketException; /** * Klassen {@code Connection} representerar antingen en anslutning från server till klient eller en slutpunkt för klienten i ett nätverk * {@code Connection}, när den är ansluten, kan utbyta data med andra parter eller parter, beroende på på en server * -implementering. *

* Den här klassen är trådsäker. * * @version 1.0 * @see Server * @see Client */ public class Anslutning implementerar Runnable {private Socket socket; privat DataOutputStream ut; privat DataInputStream i; privat trådtråd; privat slutligt objekt writeLock = nytt objekt (); privat slutligt objekt readLock = nytt objekt (); /*** Konstruerar {@code Connection} med hjälp av strömmar från en angiven {@link Socket}. * * @param -uttag Socket för att hämta strömmarna från.*/ public Connection (Socket socket) kastar NetworkException {if (socket == null) {kasta nytt IllegalArgumentException ("null socket"); } this.socket = socket; prova {out = new DataOutputStream (socket.getOutputStream ()); } catch (IOException e) {throw new NetworkException ("Det gick inte att komma åt utmatningsströmmen.", e); } prova {in = new DataInputStream (socket.getInputStream ()); } catch (IOException e) {throw new NetworkException ("Det gick inte att komma åt inmatningsström.", e); } tråd = ny tråd (detta); thread.start (); } /*** Läser meddelanden medan anslutningen till den andra parten lever. */ @Override public void run () {while (! Socket.isClosed ()) {try {int identifier; byte byte; synkroniserad (readLock) {identifier = in.readInt (); int längd = in.readInt (); if (längd> 0) {byte = ny byte [längd]; in.readFully (byte, 0, bytes.length); } annat {fortsätt; }} switch (identifierare) {case Identifier. INTERNAL: String command = new String (bytes); if (command.equals ("koppla bort")) {if (! socket.isClosed ()) {System.out.println ("Avkopplingspaket mottaget."); prova {close (); } catch (NetworkException e) {return; } } } ha sönder; case Identifier. TEXT: System.out.println ("Meddelande mottaget:" + ny sträng (byte)); ha sönder; standard: System.out.println ("Okänd data mottagen."); }} catch (SocketException e) {if (! e.getMessage (). är lika med ("Socket stängd")) {e.printStackTrace (); }} catch (IOException e) {e.printStackTrace (); }}} /*** Skickar data till den andra parten. * * @param data Data att skicka. * @kastar NetworkException Om skrivning till utdataström misslyckas. * @throws IllegalStateException Om du försöker skriva data när anslutningen stängs. * @throws IllegalArgumentException Om data som ska skickas är noll. * @throws UnsupportedOperationException Om datatyp som inte stöds ska skickas. */ public void send (Objektdata) kastar NetworkException {if (socket.isClosed ()) {kasta ny IllegalStateException ("Data skickas inte, anslutningen stängs."); } if (data == null) {kasta ny IllegalArgumentException ("null data"); } int -identifierare; byte byte; if (datainstans av sträng) {identifier = Identifier. TEXT; byte = ((String) data).getBytes (); } else {throw new UnsupportedOperationException ("Datatyp som inte stöds:" + data.getClass ()); } prova {synchronized (writeLock) {out.writeInt (identifierare); out.writeInt (bytes.length); out.write (byte); out.flush (); }} catch (IOException e) {throw new NetworkException ("Data kunde inte skickas.", e); }} /*** Skickar ett frånkopplingsmeddelande till och stänger anslutningen med den andra parten. */ public void close () kastar NetworkException {if (socket.isClosed ()) {throw new IllegalStateException ("Connection is already closed."); } prova {byte meddelande = "koppla bort".getBytes (); synkroniserad (writeLock) {out.writeInt (Identifier. INTERNAL); out.writeInt (meddelande.längd); out.write (meddelande); out.flush (); }} catch (IOException e) {System.out.println ("Det gick inte att skicka frånkopplingsmeddelande."); } prova {synchronized (writeLock) {out.close (); }} catch (IOException e) {throw new NetworkException ("Fel vid anslutning.", e); } äntligen {thread.interrupt (); }} /*** Returnerar om anslutningen till den andra parten lever eller inte. * * @return Sann om anslutningen är levande. Falskt, annars. */ public boolean isConnected () {return! socket.isClosed (); }}

Identifier.java

/** * Klassen {@code Identifier} innehåller konstanter som används av {@link Connection} för att serialisera och deserialisera data * som skickas över nätverket. * * @version 1.0 * @see Connection * / public final class Identifier { / ** * Identifier för interna meddelanden. */ public static final int INTERNAL = 1; /*** Identifierare för textmeddelanden. */ public static final int TEXT = 2; }

NetworkException.java

/*** Klassen {@code NetworkException} indikerar ett fel relaterat till nätverket. * / public class NetworkException utvidgar undantag { / *** Konstruerar en {@code NetworkException} med {@code null} som meddelande. * / public NetworkException () {} / *** Konstruerar en {@code NetworkException} med det angivna meddelandet. * * @param -meddelande Ett meddelande för att beskriva fel. */ public NetworkException (strängmeddelande) {super (meddelande); } /*** Konstruerar en {@code NetworkException} med det angivna meddelandet och orsaken. * * @param -meddelande Ett meddelande för att beskriva fel. * @param orsak En orsak till fel. */ public NetworkException (strängmeddelande, orsak som kan kastas) {super (meddelande, orsak); } /*** Konstruerar en {@code NetworkException} med den angivna orsaken. * * @param orsak En orsak till fel. */ public NetworkException (orsak som kan kastas) {super (orsak); }}

UsageExample.java

/*** Klassen {@code UsageExample} visar användningen av {@link Server} och {@link Client}. I dessa exempel används * {@link Thread#sleep (long)} för att säkerställa att varje segment körs eftersom snabb start och stängning gör att vissa * segment inte körs. * * @version 1.0 * @see Server * @see Client */ public class UsageExample {public static void main (String args) kastar undantag {String host = "localhost"; int port = 10430; Server server = ny server (värd, port); Klientklient = ny klient (värd, port); Tråd. Sover (100L); client.send ("Hej."); server.broadcast ("Hej, fella!"); Tråd. Sover (100L); server.disconnect (server.getConnections () [0]); // eller client.close () för att koppla bort från server.close () på klientsidan; }}

Rekommenderad: