Implement network communication with Java
Lu Wei
The computer communicates over the network through the TCP / UDP protocol is built on the following four-layer model:
When we write Java applications, it is mainly working in the fourth layer, ready. Generally speaking, it is not necessary to care about the TCP / UDP layer because the Java.net package has provided the system-independent underlying implementation. However, understanding TCP and UDP are necessary to determine which Java class uses, or it is necessary. The TCP protocol is based on the connection-based protocol, before communicating, first establish a connection before communicating. Therefore, it is guaranteed to communicate synchronously and accurately. If the application needs a reliable point-to-point communication, the TCP protocol is generally used. For example, HTTP, FTP, Telnet and other applications ensure that its reliability is critical to running. On the other hand, some applications are not necessarily required for communication requirements. For example, ping commands. We can also consider such an example: the server provides a clock service, which is scheduled to send time data; the client constantly extracts time data; if we have a reliable connection, if a packet is lost, the customer Request to retransmit the package, the data returned back has lost meaning. Therefore, the efficiency and applicability of the service program is reduced. Finally, we explain the following another more important concept: port. We know that data arrives at a host over the network (or accurately said that the host's network card is implemented through the IP address. But which program is it belonging when the host runs multiple programs? This is the port. One port can only bind an application. The application that communicates with TCP / UDP must know the other party's IP address and port number to communicate. The port number can be taken from 0-65535, where 0-1023 is a reserved port, providing some of the services known to well. The following figure illustrates the use of ports.
Below, we specifically analyze two Java programs to deepen the understanding of the above concepts.
First, Socket and TCP
The source code for the service programs and client programs will be listed below. Specific analysis of the comments in the code. The program can only establish a single pair of connections, but according to their principle, multi-thread multi-pair connection complex network programs can be written. The client program of the app is a separate application, but it can fully achieve the same functionality through the applet. The author implements the applet and server program's easy communication in the browser in the IE4.0 environment. However, in the environment of IE5.0, the situation has changed. The security option of IE5.0 has a certain difference from IE4.0. In any case, it is impossible to implement the effect in IE4.0, showing "xxx.xxx.xxx.xxx:4444 can not access" error information. Through analysis, I think this may be IE5.0's consideration of network security. Through analysis, I think the Applet program should communicate with the application on the server, and the server should be a web server. So, I put the server program of this application in Web Server, and the result was successful. The environment I use is, Web Server: IIS (Option Pack 3); MS VJ 6.0. // The following KkState class implements a major process of an interesting dialog process: the user launched the service program, the service program listens to the connection request from the network, // If there is a customer connection, establish a connection. Then, in the customer terminal, "knock! Knock!", The client, "Turnip" is replied to "who's there.". Customer Enter "Turnip WHO?", Answer "Turnip The Heat, IT's Cold IN here! WANT ANOTHER? (Y / N)". If the client // enters "Y", the next round of new dialogue is performed, otherwise the end. The content about the conversation is stored in two string arrays in advance.
import java.net *;. import java.io *;. class KKState {private static final int WAITING = 0; private static final int SENTKNOCKKNOCK = 1; private static final int SENTCLUE = 2; private static final int ANOTHER = 3; private Static Final Int NumJokes = 5; Private Int State = Waiting; Private Int CurrentJoke = 0; Private StringClues = {"Tumip", "Little Old Lady", "ATCH", "WHO"; "WHO"}; private stringanswers = { "Turnip The Heat, It's Cold In Here!", "I Didn't Know You Could Yodel!", "Bless You!", "Is there an offl in here", "Is there an echo in here? "}; String processInput (String theInput) {String theOutput = null; if (state == WAITING) {theOutput =" Knock Knock ";!! state = SENTKNOCKKNOCK;} else if (state == SENTKNOCKKNOCK) {if (theInput. EqualsignoreCase ("WHO's there?") {theoutput = clues [currentjoke]; state = SentClue;} else {theoutput = "} else {theoutput ="}} else {"="} else { Knock! ";}} Else if (state == SENTCLUE) {IF (theInput.equalsignorecase (Clues [CurrentJoke] " WHO? ")) { THEOUTPUT = ANSWERS [CURRENTJOKE] "WANT Another? (y / n)"; state = another;} else {theoutput = "You're supposed to say /" " clues [currentjoke] " WHO? / "" " ! Try Again.knock! Knock! "; State = SENTKNOCKNOCK;}} else if (state == Another) {if (theInput.equalsignorecase (" y ")) {theoutput =" knock! Knock! "; If (currentjoke = = (NumJokes-1)) CurrentJoke = 0 else currentjoke ; state = SENTKNOCKNOCK;} else {theoutput = "BYE."; State = waiting;
}} // server program class KnockKnockServer {public static void main (String [] args) {ServerSocket serverSocket = null; try {serverSocket = new ServerSocket (4444); // create server-side socket} catch (IOException e) {System. Out.println ("COULD NOT LISTEN ON Port:" 4444 "," E; System.exit (1);} Socket ClientSocket = NULL; Try {ClientSocket = Serversocket.accept (); // Listening Application Connection to this socket Requires and establishs the connection} catch (ioException e) {system.out.println ("Accept failed:" 4444 " e); system.exit (1);} try {// Get input data streams through the client Socket Object, by reading the information entered into the client // through the client socket, get the output data stream object, by it can input information to the client DATAINPUTSTREAM IS = New DataInputStream (New BufferedInputStream (ClientSocket.getInputStream ())) PRINTSTREAM OS = New PrintStream (ClientSocket.getputstream (ClientSocket.getputStream (), 1024); // KKState class is used to process the input session information, then return to set a good answer kkstate kks = new kkstate (): String InputLine, OutputLine; OAS.Println (OS.Println); // First run, the input parameter is NULL, KKS returns: "Knock! Knock!"; then write it to the client. 0s .flush (); // If the client is not entered, readline will block; if the client is closed, R EADLINE returns to NULL. // In the following cycle statement, the way to read a row, and write a line. While ((InputLine = Is.Readline ())! = null) {OutputLine = kks.processInput (InputLine); Os.Println (OutputLine); Os.Flush (); if (OutputLine.Equals ("bye.")) Break;} // The following completes the clearance work.
Os.close (); is.close (); clientsocket.close (); servets (ooException e) {E.PrintStackTrace ();}}} // Client Program Import Java.IO. *; import java.net *;. public class EchoTest {public static void main (Stringargs) {Socket echoSocket = null; DataOutputStream os-null; DataInputsStream is = null; DataInputStream stdIn = new DataInputStream (System.in); try {echoSocket = new Socket ( "myHost", 4444); os = new DataOutputStream (echoSocket.getOutputStream ()); is = newDataInputStream (echoSocket.getInputStream ());} catch (UnknownHostException e) {System.err.println ( "Don` T Know About Host: MyHost ");} catch (ioException e) {system.err.println (" COULDN`t Get I / O for the connection to: myhost ");} if (echosocket! = null && os! = Null && is! = null) {Try {string userinput; while ((userinput = stdin.readline ())! = null) {os.writebytes (userInput); os.WritebyTe ("/ n '); system.out.println ("Echo:" is.readline ());} os.close (); is.close (); echosocket.close ();} catch (ooexception e) {SYST Em.err.Println ("I / O Failed On The Connection TO: MyHost");}}}} II, UDP
Using UDP mode, and TCP is very different. The TCP must be created by the server side, then establish a connection request to the server side Socket by the client side, then create a Socket corresponding to the client socket and obtain the input and output flow through the socket, which, network communication is similar The way of file I / O, and the complexity of all network communication is masked by the socket mechanism (see Figure 2); simple in the case of using UDP, in communication, customer and server only involve two main Class: DataGramsocket and DataGrampacket class. The DataGrampacket class can be seen as a vector carrier, which must establish a data buffer to accommodate the specific information sent or accepted; DataGramsocket can be seen as a DataGraMpacket transmission or acceptance device, send a packet must know the transmitted host address and port The acceptance of only one packet object is used as a container (see Figure 3).
/ / This program describes: First, the server side generates a DataGramsocket to listen to a port, ready to intercept the datagram that is sent to the port. Once the client sends a datagram for the server-side machine and the port, the server receives the datagram, and acquires the send address of the datagram and the sending port, and send an answering message to the send address and port. The message content is a line of text in one-line on the server side. If the file does not exist, the current time of the server is transmitted. // server-side program: import java.io. *; Import java.net. *; Import java.util. *; // quoteserver only provides an entry for the service program, the main program flow is included in the QuoteServer Thread.
class QuoteServer {public static void main (Stringargs) {new QuoteServerThread () start ();.}} class QuoteServerThread extends Thread {private DatagramSocket socket = null; // for transmitting and receiving data packets private DataInputStream qfs = null; // Used to read one-liners.txt file quoteServertHread () {super ("quoteserver"); try {socket = new datagram (); system.out.println ("QuoteServer Listening on Port: Socket.getlocalPort ()); // Display server-side DataGramsocket port number (for client use)} catch (java.net.socketexceptione) {system.err.println ("Could Not Create DataGram socket.");} This.openInputFile ();} public Void Run () {if (socket == null) ReturnM; While (true) {type {byte [] buf = new byte [256]; // Establish a memory buffer for DataGramPacket uses DataGrampacket Packet; inetaddress address; int port; String dstring = null; packet = new data; socket.Receive (packet); // receives Dativity to this address and port address = packet.getaddress (); // Get the source sent Address port = packet.getPort (); Get the source sent port if (QFS == null) dstring = new date (). Tostring (); else D String = getNextQuote (); dstring.getbytes (0, dstring.Length (), buf, 0); packet = new data, address, port); socket.send (packet); // sent back Server-side response dataset} catch (ioExceptione) {system.err.println ("IOEXCEPTION:" E); E.PrintStackTrace ();}} }protected void finalize ()}} protected void finalize ()}} protected void finalize ()}} protected (); SOCKET = null; system.out.println ("Closing DataGram socket.");}} Private void openinputfile ()} private void openinputfile () {Try {QFS = New DataInputStream ("One-LineInputStream (" One-LineInPutStream ("One-Liners.txt"));} Catch (java.io.filenotfoundexception e) {system.err.println ("Could NOT OPEN Quote file.serving time instead);
}} private string getNextQuote () {string returnValue-null; try {if ((returnvalue = Qfs.readiine ()) == null) {qfs.close (); this.openinputFile (); returnValue = Qfs.readline () / / The file should have at least one line!}}}}}}}}}}}}}} Return ReturnValue;}} // The client must enter the form of the Java QuoteClient host name port number to run client import java.io *; impor tjava.net *;. impor tjava.util *;. class QuoteClient {public static void main (Stringargs) {int port; InetAddress address; DatagramSocket socket = null; DatagramPacket packet; bytesendBuf = new Byte [256]; if (args.length! = 2) {system.out.println ("Usage: java quoteclient