Ang pagsusulat ng code na nagpapatupad sa isang tiyak na aparato ay lubos na nagbibigay-kasiyahan. Ngunit, ang pagsulat ng code na nagpapatupad sa maraming mga aparato na nakikipag-usap sa bawat isa ay nakakumpirma lamang sa buhay. Tuturuan ka ng artikulong ito kung paano ikonekta at makipagpalitan ng mga mensahe sa network gamit ang transmission control protocol (TCP).
Sa artikulong ito, magse-set up ka ng isang application na ikonekta ang iyong computer sa sarili nito, at mahalagang, gawin itong baliw - kausapin ang sarili nito. Malalaman mo rin ang pagkakaiba sa pagitan ng dalawang pinakalawak na ginagamit na mga stream para sa networking sa Java at kung paano ito gumana.
Data at Mga Stream ng Bagay
Bago sumisid sa code, ang pagkakaiba sa pagitan ng dalawang daloy na ginamit sa artikulo ay kailangang makilala.
Mga Data Stream
Pinoproseso ng mga stream ng data ang mga primitive na uri ng data at mga string. Ang data na ipinadala sa mga stream ng data ay kailangang manu-manong na-serialize at deserialized na nagpapahirap sa paglipat ng kumplikadong data. Ngunit, ang mga data stream ay maaaring makipag-usap sa mga server at kliyente na nakasulat sa ibang mga wika kaysa sa Java. Ang mga hilaw na stream ay katulad ng mga stream ng data sa aspetong iyon, ngunit tinitiyak ng mga stream ng data na ang data ay nai-format sa isang independiyenteng paraan ng platform na kung saan ay kapaki-pakinabang dahil ang parehong partido ay makakabasa ng naipadala na data.
Mga Stream ng Bagay
Pinoproseso ng mga stream ng object ang mga primitive na uri ng data at mga bagay na nagpapatupad
Serializable
interface Ang data na ipinadala sa mga stream ng object ay awtomatikong naka-serialize at deserialized na nagpapadali sa paglipat ng kumplikadong data. Ngunit, ang mga stream ng object ay maaari lamang makipag-usap sa mga server at kliyente na nakasulat sa Java. Gayundin,
ObjectOutputStream
sa pagsisimula, nagpapadala ng isang header sa
InputStream
ng ibang partido na, sa pagsisimula, ay hinaharangan ang pagpapatupad hanggang sa matanggap ang header.
Mga hakbang
Hakbang 1. Lumikha ng isang klase
Lumikha ng isang klase at pangalanan ito subalit nais mo. Sa artikulong ito, mapangalanan ito
Halimbawa ng NetworkApp
pampublikong klase NetworkAppExample {}
Hakbang 2. Lumikha ng isang pangunahing pamamaraan
Lumikha ng isang pangunahing pamamaraan at ideklara na maaaring magtapon ng mga pagbubukod ng
Pagbubukod
uri at anumang subclass nito - lahat ng mga pagbubukod. Ito ay itinuturing na isang masamang pagsasanay, ngunit katanggap-tanggap para sa mga walang halimbawa na halimbawa.
publikong klase NetworkAppExample {public static void main (String args) throws Exception {}}
Hakbang 3. Ipahayag ang address ng server
Ang halimbawang ito ay gagamit ng lokal na host address at isang di-makatwirang numero ng port. Ang numero ng port ay kailangang nasa isang saklaw mula 0 hanggang 65535 (kasama). Gayunpaman, ang mga numero ng port upang maiwasan ang saklaw mula 0 hanggang 1023 (kasama) dahil ang mga ito ay nakareserba ng mga port ng system.
pampublikong klase NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; }}
Hakbang 4. Lumikha ng isang server
Ang server ay nakasalalay sa address at port at nakikinig para sa papasok na mga koneksyon. Sa Java,
ServerSocket
kumakatawan sa endpoint ng server-side at ang pagpapaandar nito ay tumatanggap ng mga bagong koneksyon.
ServerSocket
walang mga stream para sa pagbabasa at pagpapadala ng data dahil hindi ito kumakatawan sa koneksyon sa pagitan ng isang server at isang client.
i-import ang java.net. InetAddress; i-import ang java.net. ServerSocket; pampublikong klase NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = bagong ServerSocket (port, 50, InetAddress.getByName (host)); }}
Hakbang 5. Pag-log inception ng server
Para sa mga layunin sa pag-log, i-print sa console na nagsimula ang server.
i-import ang java.net. InetAddress; i-import ang java.net. ServerSocket; pampublikong klase NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = bagong ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Nagsimula ang server."); }}
Hakbang 6. Lumikha ng isang kliyente
Ang kliyente ay nakasalalay sa address at port ng isang server at nakikinig para sa mga packet (mensahe) pagkatapos maitaguyod ang koneksyon. Sa Java,
Socket
kumakatawan sa alinman sa isang client-side endpoint na konektado sa server o isang koneksyon (mula sa server) sa client at ginagamit upang makipag-usap sa partido sa kabilang dulo.
i-import ang java.net. InetAddress; i-import ang java.net. ServerSocket; i-import ang java.net. Socket; pampublikong klase NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = bagong ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Nagsimula ang server."); Socket client = bagong Socket (host, port); }}
Hakbang 7. Pagtatangka ng koneksyon sa pag-log
Para sa mga layunin sa pag-log, i-print sa console na tinangka ang koneksyon.
i-import ang java.net. InetAddress; i-import ang java.net. ServerSocket; i-import ang java.net. Socket; pampublikong klase NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = bagong ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Nagsimula ang server."); Socket client = bagong Socket (host, port); System.out.println ("Kumokonekta sa server …"); }}
Hakbang 8. Itaguyod ang koneksyon
Ang mga kliyente ay hindi kailanman kumokonekta maliban kung nakikinig ang server at tumatanggap, sa madaling salita ay nagtatatag, mga koneksyon. Sa Java, ang mga koneksyon ay itinatag gamit ang
tanggapin ()
paraan ng
ServerSocket
klase Harangan ng pamamaraan ang pagpapatupad hanggang kumonekta ang isang kliyente.
i-import ang java.net. InetAddress; i-import ang java.net. ServerSocket; i-import ang java.net. Socket; pampublikong klase NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = bagong ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Nagsimula ang server."); Socket client = bagong Socket (host, port); System.out.println ("Kumokonekta sa server …"); Koneksyon sa socket = server.accept (); }}
Hakbang 9. Naitaguyod ang koneksyon
Para sa mga layunin sa pag-log, i-print sa console na ang koneksyon sa pagitan ng server at client ay itinatag.
i-import ang java.net. InetAddress; i-import ang java.net. ServerSocket; i-import ang java.net. Socket; pampublikong klase NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = bagong ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Nagsimula ang server."); Socket client = bagong Socket (host, port); System.out.println ("Kumokonekta sa server …"); Koneksyon sa socket = server.accept (); System.out.println ("Naitaguyod ang koneksyon."); }}
Hakbang 10. Maghanda ng mga stream ng komunikasyon
Ang komunikasyon ay tapos na sa mga stream at, sa application na ito, ang mga hilaw na stream ng (koneksyon mula sa) server (sa client) at client ay dapat na kadena sa alinman sa data o stream ng object. Tandaan, ang parehong mga partido ay kailangang gumamit ng parehong uri ng stream.
-
Mga stream ng data
i-import ang java.io. DataInputStream; i-import ang java.io. DataOutputStream; i-import ang java.net. InetAddress; i-import ang java.net. ServerSocket; i-import ang java.net. Socket; pampublikong klase NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = bagong ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Nagsimula ang server."); Socket client = bagong Socket (host, port); System.out.println ("Kumokonekta sa server …"); Koneksyon sa socket = server.accept (); System.out.println ("Naitaguyod ang koneksyon."); DataOutputStream clientOut = bagong DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = bagong DataInputStream (client.getInputStream ()); DataOutputStream serverOut = bagong DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = bagong DataInputStream (connection.getInputStream ()); }}
-
Mga daloy ng object
Kapag ginamit ang maraming mga stream ng object, ang mga input stream ay dapat na mapasimula sa parehong pagkakasunud-sunod ng mga output stream dahil
ObjectOutputStream
nagpapadala ng isang header sa kabilang partido at
ObjectInputStream
hinaharangan hanggang sa mabasa ang header.
i-import ang java.io. ObjectInputStream; i-import ang java.io. ObjectOutputStream; i-import ang java.net. InetAddress; i-import ang java.net. ServerSocket; i-import ang java.net. Socket; pampublikong klase NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = bagong ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Nagsimula ang server."); Socket client = bagong Socket (host, port); System.out.println ("Kumokonekta sa server …"); Koneksyon sa socket = server.accept (); System.out.println ("Naitaguyod ang koneksyon."); ObjectOutputStream clientOut = bagong ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = bagong ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = bagong ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = bagong ObjectInputStream (connection.getInputStream ()); }}
Ang order bilang tinukoy sa code sa itaas ay maaaring mas madaling tandaan - unang gawing simula ang mga output stream pagkatapos ay mag-input ng mga stream sa parehong pagkakasunud-sunod. Gayunpaman, ang isa pang order para sa pagsisimula ng mga stream ng object ay ang mga sumusunod:
ObjectOutputStream clientOut = bagong ObjectOutputStream (client.getOutputStream ()); ObjectInputStream serverIn = bagong ObjectInputStream (connection.getInputStream ()); ObjectOutputStream serverOut = bagong ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = bagong ObjectInputStream (client.getInputStream ());
Hakbang 11. Mag-log na ang komunikasyon ay handa na
Para sa mga layunin sa pag-log, i-print sa console na handa na ang komunikasyon.
// code tinanggal ang pag-import ng java.net. InetAddress; i-import ang java.net. ServerSocket; i-import ang java.net. Socket; pampublikong klase NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = bagong ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Nagsimula ang server."); Socket client = bagong Socket (host, port); System.out.println ("Kumokonekta sa server …"); Koneksyon sa socket = server.accept (); System.out.println ("Naitaguyod ang koneksyon."); // code omitted System.out.println ("Handa na ang komunikasyon."); }}
Hakbang 12. Lumikha ng isang mensahe
Sa application na ito,
Kamusta Mundo
ang teksto ay ipapadala sa server bilang
byte
o
String
. Ipahayag ang isang variable ng uri na nakasalalay sa ginamit na stream. Gamitin
byte
para sa mga stream ng data at
String
para sa mga stream ng object.
-
Mga stream ng data
Gamit ang mga stream ng data, ang serialization ay ginagawa sa pamamagitan ng pag-convert ng mga bagay sa primitive na uri ng data o a
String
. Sa kasong ito,
String
ay na-convert sa
byte
sa halip na nakasulat gamit
magsulatBytes ()
paraan upang maipakita kung paano ito magagawa sa iba pang mga bagay, tulad ng mga imahe o iba pang mga file.
i-import ang java.io. DataInputStream; i-import ang java.io. DataOutputStream; i-import ang java.net. InetAddress; i-import ang java.net. ServerSocket; i-import ang java.net. Socket; pampublikong klase NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = bagong ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Nagsimula ang server."); Socket client = bagong Socket (host, port); System.out.println ("Kumokonekta sa server …"); Koneksyon sa socket = server.accept (); System.out.println ("Naitaguyod ang koneksyon."); DataOutputStream clientOut = bagong DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = bagong DataInputStream (client.getInputStream ()); DataOutputStream serverOut = bagong DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = bagong DataInputStream (connection.getInputStream ()); System.out.println ("Ang komunikasyon ay handa na."); byte messageOut = "Hello World".getBytes (); }}
-
Mga daloy ng object
i-import ang java.io. ObjectInputStream; i-import ang java.io. ObjectOutputStream; i-import ang java.net. InetAddress; i-import ang java.net. ServerSocket; i-import ang java.net. Socket; pampublikong klase NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = bagong ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Nagsimula ang server."); Socket client = bagong Socket (host, port); System.out.println ("Kumokonekta sa server …"); Koneksyon sa socket = server.accept (); System.out.println ("Naitaguyod ang koneksyon."); ObjectOutputStream clientOut = bagong ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = bagong ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = bagong ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = bagong ObjectInputStream (connection.getInputStream ()); System.out.println ("Ang komunikasyon ay handa na."); String messageOut = "Hello World"; }}
Hakbang 13. Ipadala ang mensahe
Sumulat ng data sa output stream at i-flush ang stream upang matiyak na ang data ay nasulat nang buo.
-
Mga stream ng data
Ang haba ng isang mensahe ay kailangang maipadala muna upang malaman ng ibang partido kung gaano karaming mga byte ang kailangang basahin. Matapos maipadala ang haba bilang isang primitive na integer type, maaaring maipadala ang mga byte.
i-import ang java.io. DataInputStream; i-import ang java.io. DataOutputStream; i-import ang java.net. InetAddress; i-import ang java.net. ServerSocket; i-import ang java.net. Socket; pampublikong klase NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = bagong ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Nagsimula ang server."); Socket client = bagong Socket (host, port); System.out.println ("Kumokonekta sa server …"); Koneksyon sa socket = server.accept (); System.out.println ("Naitaguyod ang koneksyon."); DataOutputStream clientOut = bagong DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = bagong DataInputStream (client.getInputStream ()); DataOutputStream serverOut = bagong DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = bagong DataInputStream (connection.getInputStream ()); System.out.println ("Ang komunikasyon ay handa na."); byte messageOut = "Hello World".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); }}
-
Mga daloy ng object
i-import ang java.io. ObjectInputStream; i-import ang java.io. ObjectOutputStream; i-import ang java.net. InetAddress; i-import ang java.net. ServerSocket; i-import ang java.net. Socket; pampublikong klase NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = bagong ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Nagsimula ang server."); Socket client = bagong Socket (host, port); System.out.println ("Kumokonekta sa server …"); Koneksyon sa socket = server.accept (); System.out.println ("Naitaguyod ang koneksyon."); ObjectOutputStream clientOut = bagong ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = bagong ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = bagong ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = bagong ObjectInputStream (connection.getInputStream ()); System.out.println ("Ang komunikasyon ay handa na."); String messageOut = "Hello World"; clientOut.writeObject (messageOut); clientOut.flush (); }}
Hakbang 14. Mag-log ng mensahe na ipinadala
Para sa mga layunin sa pag-log, i-print sa console na ipinadala ang mensahe.
-
Mga stream ng data
i-import ang java.io. DataInputStream; i-import ang java.io. DataOutputStream; i-import ang java.net. InetAddress; i-import ang java.net. ServerSocket; i-import ang java.net. Socket; pampublikong klase NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = bagong ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Nagsimula ang server."); Socket client = bagong Socket (host, port); System.out.println ("Kumokonekta sa server …"); Koneksyon sa socket = server.accept (); System.out.println ("Naitaguyod ang koneksyon."); DataOutputStream clientOut = bagong DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = bagong DataInputStream (client.getInputStream ()); DataOutputStream serverOut = bagong DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = bagong DataInputStream (connection.getInputStream ()); System.out.println ("Ang komunikasyon ay handa na."); byte messageOut = "Hello World".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Ipinadala ang mensahe sa server:" + bagong String (messageOut)); }}
-
Mga daloy ng object
i-import ang java.io. ObjectInputStream; i-import ang java.io. ObjectOutputStream; i-import ang java.net. InetAddress; i-import ang java.net. ServerSocket; i-import ang java.net. Socket; pampublikong klase NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = bagong ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Nagsimula ang server."); Socket client = bagong Socket (host, port); System.out.println ("Kumokonekta sa server …"); Koneksyon sa socket = server.accept (); System.out.println ("Naitaguyod ang koneksyon."); ObjectOutputStream clientOut = bagong ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = bagong ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = bagong ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = bagong ObjectInputStream (connection.getInputStream ()); System.out.println ("Ang komunikasyon ay handa na."); String messageOut = "Hello World"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Ipinadala ang mensahe sa server:" + messageOut); }}
Hakbang 15. Basahin ang mensahe
Basahin ang data mula sa input stream at i-convert ito. Dahil alam namin nang eksakto ang uri ng ipinadalang data, gagawa kami ng alinman sa
String
mula sa
byte
o cast
Bagay
sa
String
nang hindi sinusuri, nakasalalay sa ginamit na stream.
-
Mga stream ng data
Tulad ng haba na ipinadala muna at byte pagkatapos, ang pagbabasa ay kailangang gawin sa parehong pagkakasunud-sunod. Kung sakaling ang haba ay zero, walang mabasa. Ang object ay deserialized kapag ang mga byte ay nai-convert pabalik sa isang halimbawa, sa kasong ito, ng
String
i-import ang java.io. DataInputStream; i-import ang java.io. DataOutputStream; i-import ang java.net. InetAddress; i-import ang java.net. ServerSocket; i-import ang java.net. Socket; pampublikong klase NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = bagong ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Nagsimula ang server."); Socket client = bagong Socket (host, port); System.out.println ("Kumokonekta sa server …"); Koneksyon sa socket = server.accept (); System.out.println ("Naitaguyod ang koneksyon."); DataOutputStream clientOut = bagong DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = bagong DataInputStream (client.getInputStream ()); DataOutputStream serverOut = bagong DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = bagong DataInputStream (connection.getInputStream ()); System.out.println ("Ang komunikasyon ay handa na."); byte messageOut = "Hello World".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Ipinadala ang mensahe sa server:" + bagong String (messageOut)); int haba = serverIn.readInt (); kung (haba> 0) {byte messageIn = bagong byte [haba]; serverIn.readFully (messageIn, 0, messageIn.length); }}}
-
Mga daloy ng object
i-import ang java.io. ObjectInputStream; i-import ang java.io. ObjectOutputStream; i-import ang java.net. InetAddress; i-import ang java.net. ServerSocket; i-import ang java.net. Socket; pampublikong klase NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = bagong ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Nagsimula ang server."); Socket client = bagong Socket (host, port); System.out.println ("Kumokonekta sa server …"); Koneksyon sa socket = server.accept (); System.out.println ("Naitaguyod ang koneksyon."); ObjectOutputStream clientOut = bagong ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = bagong ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = bagong ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = bagong ObjectInputStream (connection.getInputStream ()); System.out.println ("Ang komunikasyon ay handa na."); String messageOut = "Hello World"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Ipinadala ang mensahe sa server:" + messageOut); String messageIn = (String) serverIn.readObject (); }}
Hakbang 16. Mag-log read message
Para sa mga layunin sa pag-log, i-print sa console na natanggap ang mensahe at i-print ang nilalaman nito.
-
Mga stream ng data
i-import ang java.io. DataInputStream; i-import ang java.io. DataOutputStream; i-import ang java.net. InetAddress; i-import ang java.net. ServerSocket; i-import ang java.net. Socket; pampublikong klase NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = bagong ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Nagsimula ang server."); Socket client = bagong Socket (host, port); System.out.println ("Kumokonekta sa server …"); Koneksyon sa socket = server.accept (); System.out.println ("Naitaguyod ang koneksyon."); DataOutputStream clientOut = bagong DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = bagong DataInputStream (client.getInputStream ()); DataOutputStream serverOut = bagong DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = bagong DataInputStream (connection.getInputStream ()); System.out.println ("Ang komunikasyon ay handa na."); byte messageOut = "Hello World".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Ipinadala ang mensahe sa server:" + bagong String (messageOut)); int haba = serverIn.readInt (); kung (haba> 0) {byte messageIn = bagong byte [haba]; serverIn.readFully (messageIn, 0, messageIn.length); System.out.println ("Natanggap ang mensahe mula sa client:" + bagong String (messageIn)); }}}
-
Mga daloy ng object
i-import ang java.io. ObjectInputStream; i-import ang java.io. ObjectOutputStream; i-import ang java.net. InetAddress; i-import ang java.net. ServerSocket; i-import ang java.net. Socket; pampublikong klase NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = bagong ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Nagsimula ang server."); Socket client = bagong Socket (host, port); System.out.println ("Kumokonekta sa server …"); Koneksyon sa socket = server.accept (); System.out.println ("Naitaguyod ang koneksyon."); ObjectOutputStream clientOut = bagong ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = bagong ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = bagong ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = bagong ObjectInputStream (connection.getInputStream ()); System.out.println ("Ang komunikasyon ay handa na."); String messageOut = "Hello World"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Ipinadala ang mensahe sa server:" + messageOut); String messageIn = (String) serverIn.readObject (); System.out.println ("Natanggap ang mensahe mula sa client:" + messageIn); }}
Hakbang 17. Idiskonekta ang mga koneksyon
Nakakonekta ang koneksyon kapag nagsara ang isang partido ng mga stream nito. Sa Java, sa pamamagitan ng pagsasara ng output stream, ang nauugnay na socket at input stream ay sarado, pati na rin. Kapag nalaman ng isang partido sa kabilang dulo na patay na ang koneksyon, kailangan din nitong isara ang output stream nito, upang maiwasan ang paglabas ng memorya.
// code tinanggal ang pag-import ng java.net. InetAddress; i-import ang java.net. ServerSocket; i-import ang java.net. Socket; pampublikong klase NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = bagong ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Nagsimula ang server."); Socket client = bagong Socket (host, port); System.out.println ("Kumokonekta sa server …"); Koneksyon sa socket = server.accept (); System.out.println ("Naitaguyod ang koneksyon."); // code omitted System.out.println ("Handa na ang komunikasyon."); // code tinanggal clientOut.close (); serverOut.close (); }}
Hakbang 18. Pag-disconnect ng pag-log
Para sa mga layunin sa pag-log, naka-disconnect ang pag-print sa mga koneksyon sa console.
// code tinanggal ang pag-import ng java.net. InetAddress; i-import ang java.net. ServerSocket; i-import ang java.net. Socket; pampublikong klase NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = bagong ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Nagsimula ang server."); Socket client = bagong Socket (host, port); System.out.println ("Kumokonekta sa server …"); Koneksyon sa socket = server.accept (); System.out.println ("Naitaguyod ang koneksyon."); // code omitted System.out.println ("Handa na ang komunikasyon."); // code tinanggal clientOut.close (); serverOut.close (); System.out.println ("Sarado ang mga koneksyon."); }}
Hakbang 19. Tapusin ang server
Ang mga koneksyon ay naka-disconnect, ngunit ang server ay pa rin tumatakbo at tumatakbo. Bilang
ServerSocket
ay hindi naiugnay sa anumang stream, kailangan itong malinaw na sarado sa pamamagitan ng pagtawag
isara ()
pamamaraan
// code tinanggal ang pag-import ng java.net. InetAddress; i-import ang java.net. ServerSocket; i-import ang java.net. Socket; pampublikong klase NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = bagong ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Nagsimula ang server."); Socket client = bagong Socket (host, port); System.out.println ("Kumokonekta sa server …"); Koneksyon sa socket = server.accept (); System.out.println ("Naitaguyod ang koneksyon."); // code omitted System.out.println ("Handa na ang komunikasyon."); // code tinanggal clientOut.close (); serverOut.close (); System.out.println ("Sarado ang mga koneksyon."); server.close (); }}
Hakbang 20. Pagwawakas ng pag-log server
Para sa mga layunin sa pag-log, ang pag-print sa console server ay natapos na.
// code tinanggal ang pag-import ng java.net. InetAddress; i-import ang java.net. ServerSocket; i-import ang java.net. Socket; pampublikong klase NetworkAppExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; ServerSocket server = bagong ServerSocket (port, 50, InetAddress.getByName (host)); System.out.println ("Nagsimula ang server."); Socket client = bagong Socket (host, port); System.out.println ("Kumokonekta sa server …"); Koneksyon sa socket = server.accept (); System.out.println ("Naitaguyod ang koneksyon."); // code omitted System.out.println ("Handa na ang komunikasyon."); // code tinanggal clientOut.close (); serverOut.close (); System.out.println ("Sarado ang mga koneksyon."); server.close (); System.out.println ("Natapos ang server."); }}
Hakbang 21. Compile at tumakbo
Pinapagana kami ng pag-log upang malaman kung ang application ay matagumpay o hindi. Inaasahang output:
Nagsimula ang server. Kumokonekta sa server… Naitaguyod ang koneksyon. Handa na ang komunikasyon. Ipinadala ang mensahe sa server: Kamusta Mundo ng Mensahe na natanggap mula sa kliyente: Kamusta sa Mga Koneksyon sa Daigdig ay sarado. Winakasan ang server.
Kung sakaling ang iyong output ay hindi katulad ng nasa itaas, na malamang na hindi mangyari, may ilang mga solusyon:
-
Kung ang output ay hihinto sa linya
Ang koneksyon ay itinatag.
at ginagamit ang mga stream ng object, i-flush ang bawat isa
ObjectOutputStream
- kaagad pagkatapos ng pagsisimula dahil ang mga header, sa ilang kadahilanan, ay hindi naipadala.
-
Kung ang output ay naglilimbag
java.net. BindException: Ginagamit na ang address
- pumili ng ibang numero ng port dahil ang isang tinukoy ay ginamit na.
Mga Tip
- Ang pagkonekta sa isang server sa ibang network ay ginagawa sa pamamagitan ng pagkonekta sa panlabas na IP address ng isang aparato na nagpapatakbo sa server na may isang naipasa na port.
- Ang pagkonekta sa isang server sa parehong network ay ginagawa sa pamamagitan ng alinman sa pagkonekta sa pribadong IP address ng isang aparato na nagpapatakbo ng server o nagpapasa ng isang port at kumokonekta sa panlabas na IP address ng aparato.
- Mayroong software, tulad ng Hamachi, na pinapayagan ang pagkonekta sa server sa ibang network nang hindi nagpapasa ng isang port, ngunit nangangailangan ito ng pag-install ng software sa parehong mga aparato.
Mga halimbawa
Ang mga application ng network na gumagamit ng pag-block ng input / output ay kailangang gumamit ng mga thread. Ang mga sumusunod na halimbawa ay nagpapakita ng isang minimalistic server at pagpapatupad ng client na may mga thread. Ang code ng pag-network ay mahalagang kapareho ng sa artikulo maliban sa ilang mga snippet na na-synchronize, inilipat sa mga thread at ang mga pagbubukod ay pinangangasiwaan.
Server.java
i-import ang java.io. IOException; i-import ang java.net. InetAddress; i-import ang java.net. ServerSocket; i-import ang java.net. SocketException; i-import ang java.net. UnknownHostException; import java.util. ArrayList; i-import ang java.util. Collection; import java.util. List; / ** * Ang klase na {@code Server} ay kumakatawan sa isang end-point ng server sa isang network. Ang {@code Server} na nakatali sa isang tiyak na IP * address at port, nagtataguyod ng mga koneksyon sa mga kliyente at nakapag-usap sa kanila o idiskonekta ang mga ito. *
* Ang klase na ito ay threadsafe. * * @version 1.0 * @see Client * @see Koneksyon * / pampublikong klase Ang server ay nagpapatupad ng Runnable {pribadong ServerSocket server; pribadong Listahan
mga koneksyon; pribadong thread ng Thread; pribadong panghuling koneksyon sa BagayLock = bagong Bagay (); / ** * Bumubuo ng isang {@code Server} na nakikipag-ugnay sa mga kliyente sa tinukoy na pangalan ng host at port na may tinukoy na * hiniling na maximum na haba ng isang pila ng mga papasok na kliyente. * * @param host Host address na gagamitin. * @param port Port number na gagamitin. * @param backlog Humiling ng maximum na haba ng pila ng mga papasok na kliyente. * @ Throws NetworkException Kung nangyayari ang error habang nagsisimula ang isang server. * / public Server (String host, int port, int backlog) ay nagtatapon ng NetworkException {try {server = new ServerSocket (port, backlog, InetAddress.getByName (host)); } catch (UnknownHostException e) {magtapon ng bagong NetworkException ("Hindi malulutas ang pangalan ng host:" + host, e); } catch (IllegalArgumentException e) {magtapon ng bagong NetworkException ("Ang numero ng port ay kailangang nasa pagitan ng 0 at 65535 (kasama):" + port); } catch (IOException e) {magtapon ng bagong NetworkException ("Hindi masimulan ang server.", e); } mga koneksyon = Collections.synchronizedList (bagong ArrayList ()); thread = bagong Thread (ito); thread.start (); } / ** * Bumubuo ng isang {@code Server} na nakikipag-ugnay sa mga kliyente sa tinukoy na pangalan ng host at port. * * @param host Host address upang magbigkis. * Ang numero ng port sa @param port upang mabuklod. * @ Throws NetworkException Kung nangyayari ang mga error habang nagsisimula ang isang server. * / pampublikong Server (String host, int port) ay nagtatapon ng NetworkException {ito (host, port, 50); } / ** * Nakikinig para sa, tumatanggap at nagrerehistro ng mga papasok na koneksyon mula sa mga kliyente. * / @Override public void run () {habang (! Server.isClosed ()) {subukan {connection.add (bagong Koneksyon (server.accept ())); } catch (SocketException e) {if (! e.getMessage (). katumbas ("Socket closed")) {e.printStackTrace (); }} catch (NetworkException | IOException e) {e.printStackTrace (); }}} / ** * Nagpapadala ng data sa lahat ng mga nakarehistrong kliyente. * * @param data Data upang ipadala. * @ Throws IllegalStateException Kung susubukan ang pagsusulat ng data kapag offline ang server. * @ Throws IllegalArgumentException Kung ang data na ipadala ay null. * / public void broadcast (object data) {if (server.isClosed ()) {magtapon ng bagong IllegalStateException ("Hindi ipinadala ang data, offline ang server."); } kung (data == null) {magtapon ng bagong IllegalArgumentException ("null data"); } na-synchronize (mga koneksyonLock) {para sa (Koneksyon sa koneksyon: mga koneksyon) {subukan {connection.send (data); System.out.println ("Matagumpay na naipadala ang data sa client."); } catch (NetworkException e) {e.printStackTrace (); }}}} / ** * Nagpadala ng isang mensahe ng pagdiskonekta at ididiskonekta ang tinukoy na kliyente. * * Koneksyon sa @param Client upang idiskonekta. * @ Throws NetworkException Kung nangyayari ang error habang isinasara ang koneksyon. * / public void disconnect (Koneksyon sa koneksyon) ay nagtatapon ng NetworkException {kung (connection.remove (connection)) {connection.close (); }} / ** * Nagpapadala ng isang mensahe ng pagdiskonekta sa lahat ng mga kliyente, ididiskonekta ang mga ito at winakasan ang server. * / public void close () nagtatapon ng NetworkException na {synchronize (mga koneksyonLock) {para sa (Koneksyon sa koneksyon: mga koneksyon) {subukan {connection.close (); } catch (NetworkException e) {e.printStackTrace (); }}} mga koneksyon. malinaw (); subukan ang {server.close (); } catch (IOException e) {magtapon ng bagong NetworkException ("Error habang isinasara ang server."); } sa wakas {thread.interrupt (); }} / ** * Ibinabalik kung ang server ay online o hindi. * * @return True kung online ang server. Mali, kung hindi man. * / public boolean isOnline () {return! server.isClosed (); } / ** * Nagbabalik ng isang hanay ng mga nakarehistrong kliyente. * / public Connection getConnections () {synchronize (mga koneksyonLock) {bumalik sa mga koneksyon.toArray (bagong Koneksyon [mga koneksyon.size ()]); }}}
Client.java
i-import ang java.io. IOException; i-import ang java.net. Socket; i-import ang java.net. UnknownHostException; / ** * Ang klase na {@code Client} ay kumakatawan sa isang end-point ng client sa isang network. Ang {@code Client}, sa sandaling nakakonekta sa isang tiyak na * server, ay garantisadong makikipag-usap lamang sa server. Natanggap man o hindi ng ibang mga kliyente ang data * nakasalalay sa pagpapatupad ng server. *
* Ang klase na ito ay threadsafe. * * @version 1.0 * @see Server * @see Connection * / pampublikong klase Client {pribadong koneksyon sa Koneksyon; / ** * Bumubuo ng isang {@code Client} na konektado sa server sa tinukoy na host at port. * * @param host Host address upang magbigkis. * Ang numero ng port sa @param port upang mabuklod. * @ Throws NetworkException Kung nangyayari ang error habang nagsisimula ang isang server. * / public Client (String host, int port) ay nagtatapon ng NetworkException {try {connection = new Connection (bagong Socket (host, port)); } catch (UnknownHostException e) {magtapon ng bagong NetworkException ("Hindi malutas ang pangalan ng host:" + host, e); } catch (IllegalArgumentException e) {magtapon ng bagong NetworkException ("Ang numero ng port ay kailangang nasa pagitan ng 0 at 65535 (kasama):" + port); } catch (IOException e) {magtapon ng bagong NetworkException ("Hindi masimulan ang server.", e); }} / ** * Nagpapadala ng data sa ibang partido. * * @param data Data upang ipadala. * @ Throws NetworkException Kung nabigo ang pagsusulat sa output stream. * @ Throws IllegalStateException Kung ang pagsusulat ng data ay tinangka kapag ang koneksyon ay sarado. * @ Throws IllegalArgumentException Kung ang data na ipadala ay null. * @ Throws UnsupportedOperationException Kung ang hindi sinusuportahang uri ng data ay tinangkang ipadala. * / public void send (object data) ay nagtatapon ng NetworkException {connection.send (data); } / ** * Nagpadala ng isang mensahe ng pagdiskonekta sa, at isinasara ang koneksyon sa, ang server. * / public void close () nagtatapon ng NetworkException {connection.close (); } / ** * Ibinabalik kung nakakonekta o hindi ang client sa server. * * @return True kung ang client ay konektado. Mali, kung hindi man. * / public boolean isOnline () {return connection.isConnected (); } / ** * Ibinabalik ang instance ng {@link Connection} ng client. * / pampublikong Koneksyon getConnection () {bumalik na koneksyon; }}
Koneksyon.java
i-import ang java.io. DataInputStream; i-import ang java.io. DataOutputStream; i-import ang java.io. IOException; i-import ang java.net. Socket; i-import ang java.net. SocketException; / ** * Ang klase na {@code Connection} ay kumakatawan sa alinman sa isang koneksyon mula sa server patungo sa client o isang end-point ng client sa isang network * {@code Connection}, sa sandaling nakakonekta, ay maaaring makipagpalitan ng data sa ibang partido o partido, depende sa isang pagpapatupad ng server *. *
* Ang klase na ito ay threadsafe. * * @version 1.0 * @see Server * @see Client * / pampublikong klase na Koneksyon ay nagpapatupad ng Runnable {pribadong Socket socket; pribadong DataOutputStream out; pribadong DataInputStream sa; pribadong thread ng Thread; pribadong pangwakas na Object writeLock = bagong Bagay (); pribadong pangwakas na object readLock = bagong Bagay (); / ** * Bumubuo ng {@code Connection} gamit ang mga stream ng isang tinukoy na {@link Socket}. * * @param socket Socket upang makuha ang mga stream mula sa.* / pampublikong Koneksyon (Socket socket) ay nagtatapon ng NetworkException {kung (socket == null) {magtapon ng bagong IllegalArgumentException ("null socket"); } this.socket = socket; subukan ang {out = bagong DataOutputStream (socket.getOutputStream ()); } catch (IOException e) {magtapon ng bagong NetworkException ("Hindi ma-access ang output stream.", e); } subukan ang {in = bagong DataInputStream (socket.getInputStream ()); } catch (IOException e) {magtapon ng bagong NetworkException ("Hindi ma-access ang input stream.", e); } thread = bagong Thread (ito); thread.start (); } / ** * Nagbabasa ng mga mensahe habang buhay ang koneksyon sa ibang partido. * / @Override public void run () {habang (! Socket.isClosed ()) {subukan {int identifier; byte bytes; sinabay (readLock) {identifier = in.readInt (); int haba = in.readInt (); kung (haba> 0) {bytes = bagong byte [haba]; in.readFully (bytes, 0, bytes.length); } iba pa {magpatuloy; }} switch (identifier) {case Identifier. INTERNAL: String command = bagong String (bytes); kung (command.equals ("idiskonekta")) {kung (! socket.isClosed ()) {System.out.println ("Natanggap na packet ng pagkakakonekta."); subukan ang {close (); } catch (NetworkException e) {bumalik; } } } pahinga; case Identifier. TEXT: System.out.println ("Natanggap ang mensahe:" + bagong String (bytes)); pahinga; default: System.out.println ("Natanggap na hindi kilalang data."); }} catch (SocketException e) {if (! e.getMessage (). katumbas ("Socket closed")) {e.printStackTrace (); }} catch (IOException e) {e.printStackTrace (); }}} / ** * Nagpapadala ng data sa ibang partido. * * @param data Data upang ipadala. * @ Throws NetworkException Kung nabigo ang pagsusulat sa output stream. * @ Throws IllegalStateException Kung ang pagsusulat ng data ay tinangka kapag ang koneksyon ay sarado. * @ Throws IllegalArgumentException Kung ang data na ipadala ay null. * @ Throws UnsupportedOperationException Kung ang hindi sinusuportahang uri ng data ay tinangkang ipadala. * / public void send (object data) ay nagtatapon ng NetworkException {kung (socket.isClosed ()) {magtapon ng bagong IllegalStateException ("Hindi ipinadala ang data, ang koneksyon ay sarado."); } kung (data == null) {magtapon ng bagong IllegalArgumentException ("null data"); } int identifier; byte bytes; kung (data instanceof String) {identifier = Identifier. TEXT; bytes = ((String) data).getBytes (); } iba pa {magtapon ng bagong UnsupportedOperationException ("Hindi sinusuportahang uri ng data:" + data.getClass ()); } subukan ang {synchronize (writeLock) {out.writeInt (identifier); out.writeInt (bytes.length); palabas. magsulat (bytes); palabas.flush (); }} catch (IOException e) {magtapon ng bagong NetworkException ("Hindi maipadala ang data.", e); }} / ** * Nagpadala ng isang mensahe ng pagdiskonekta sa, at isinasara ang koneksyon sa, ang iba pang partido. * / public void close () throws NetworkException {if (socket.isClosed ()) {throw new IllegalStateException ("Sarado na ang koneksyon."); } subukan ang {byte message = "idiskonekta".getBytes (); naka-synchronize (magsulatLock) {out.writeInt (Identifier. INTERNAL); out.writeInt (message.length); labas. magsulat (mensahe); palabas.flush (); }} catch (IOException e) {System.out.println ("Hindi maipadala ang mensahe ng pagkakakonekta."); } subukan ang {synchronize (writeLock) {out.close (); }} catch (IOException e) {magtapon ng bagong NetworkException ("Error habang isinasara ang koneksyon.", e); } sa wakas {thread.interrupt (); }} / ** * Ibinabalik kung buhay o hindi ang koneksyon sa kabilang partido. * * @return True kung buhay ang koneksyon. Mali, kung hindi man. * / public boolean isConnected () {return! socket.isClosed (); }}
Kilalanin.java
/ ** * Naglalaman ang klase ng {@code Identifier} ng mga Constant na ginagamit ng {@link Connection} para sa serializing at deserializing ang data * na ipinadala sa network. * * @version 1.0 * Koneksyon sa @see * / Public final class Identifier {/ ** * Identifier para sa mga panloob na mensahe. * / public static final int INTERNAL = 1; / ** * Identifier para sa mga tekstuwal na mensahe. * / public static final int TEXT = 2; }
NetworkException.java
/ ** * Ang klase na {@code NetworkException} ay nagpapahiwatig ng isang error na nauugnay sa network. * / pampublikong klase Ang NetworkException ay nagpapalawak ng Exception {/ ** * Bumubuo ng isang {@code NetworkException} na may {@code null} bilang mensahe nito. * / public NetworkException () {} / ** * Bumubuo ng isang {@code NetworkException} kasama ang tinukoy na mensahe. * * @param message Isang mensahe upang ilarawan ang error. * / public NetworkException (String message) {super (mensahe); } / ** * Bumubuo ng isang {@code NetworkException} na may tinukoy na mensahe at sanhi. * * @param message Isang mensahe upang ilarawan ang error. * @param sanhi Isang sanhi ng error. * / public NetworkException (String message, Throwable sanhi) {super (mensahe, sanhi); } / ** * Bumubuo ng isang {@code NetworkException} na may tinukoy na dahilan. * * @param sanhi Isang sanhi ng error. * / public NetworkException (Throwable sanhi) {super (sanhi); }}
PaggamitExample.java
/ ** * Ipinapakita ng klase na {@code UsageExample} ang paggamit ng {@link Server} at {@link Client}. Ang mga halimbawang ito ay gumagamit ng * {@ link Thread # sleep (haba)} upang matiyak na naisakatuparan ang bawat segment sapagkat ang mabilis na pagsisimula at pagsasara ay sanhi ng hindi pagpapatupad ng ilang * mga segment. * * @version 1.0 * @see Server * @see Client * / public class UsageExample {public static void main (String args) throws Exception {String host = "localhost"; int port = 10430; Server server = bagong Server (host, port); Client client = bagong Client (host, port); Thread.tulog (100L); client.send ("Hello."); server.broadcast ("Hoy, fella!"); Thread.tulog (100L); server.disconnect (server.getConnections () [0]); // o client.close () upang idiskonekta mula sa client-side server.close (); }}