Using Java Development Network software is very convenient and powerful, this power of Java is derived from his unique set of powerful APIs, which are a series of classes and interfaces, all located in Package Java.net and Javax. Net. In this article, we will introduce the sockets, while explaining how to use the NetWork API manipulator, after completing this article, you can write low-end communications software.
What is a socket?
The Network API is a typical TCP / IP network Java program to communicate with other program communication, and the Network API relies on Socket for communication. Socket can be seen as one endpoint in the communication connection in the two programs, and a program writes a piece of information into the Socket, which sends this information to another Socket so that this information can be transmitted to other programs. Figure 1
Let's analyze the programs on Host A. Procedure A to write a section into socket, Socket is accessed by Host A network management software, and sends this information through Host A network interface card to Host B, After the Host B network interface card is received, the network management software transmitted to the Host B is transmitted, and the network management software saves this information in the Host B socket, and then the program B can read this information in the socket.
Suppose the third host Host C is added to the network of Figure 1, then how does Host A know that the information is transmitted correctly to Host B instead of being transferred to Host C? Each host based on the TCP / IP network is given a unique IP address. The IP address is a 32-bit unsigned integer. Since it is not converted to binary, it is usually separated by a decimal point, such as: 198.163.227.6, just as The IP addresses are all consisting of four parts, each of which is 0-255 to represent an 8-bit address.
It is worth noting that the IP address is 32-bit address. This is the IP Protocol version 4 (IPv4) specified. Currently since IPv4 addresses are nearly exhausted, IPv6 addresses are gradually replacing IPv4 addresses. The IPv6 address is 128 Symbol integer.
Suppose the second program is added to Host B of the network of Figure 1, then how can the information from Host A can be correctly transmitted to program b instead of passing to newly joined programs? This is because each TCP / IP network communication program is given a unique port and port number. The port is an information buffer for retaining the input / output information in the socket. The port number is a 16-bit unsigned symbol. Integer, the range is 0-65535 to distinguish every program on the host (port number is like a room number in the house), the short slogan below 256 is reserved to the standard application, such as the port number of POP3 is 110, each The sockets are combined into the IP address, port, port number, which can distinguish every socket T, let's talk about two sockets: Flow socket and self-address data Socket.
Stream socket
Whenever, when sending and receiving information between two network applications, a reliable connection is required, and the flow cover is relying on the TCP protocol to ensure that the information is properly reached. In fact, the IP package may be in the network. Lost or errors during the transfer, any case occurs, and the TCP, which is the acceptor, resensively, re-sends this IP package. This is the so-called establishing a reliable connection between two flow sockets.
Flow socket plays a necessary role in the C / S program, the client program (the network application that needs to access some services) creates an IP address and server program for hosting the server's host (provided for client applications) The port number of the port number of the service network application. The initialization code of the client-end socket passes the IP address and port number to the network management software of the client host, and the management software passes the IP address and port number to the server host by NIC; the server-side host reads the NIC transmission Data, then check if the server program is in the listening state, which is still performed by a socket and port; if the server program is listening, the server-side network management software issues a positive After receiving the response signal, the client flow sleeve initialization code creates a port number to the client program, and passes the port number to the server program (the server program will use this port number to identify Whether the information belongs to a client program) At the same time, the initialization of the stream sleeve is completed.
If the server program is not in the listening state, the server-side network management software will pass a negative signal to the client. After receiving this negative signal, the client's flow sleeve initialization code will throw an exception object and do not establish a communication connection. Nor creating a streamlined temple object. This situation is like calling, when someone is established, otherwise the phone will hang.
This part of the work includes three classes of associated: Inetaddress, Socket, and Serversocket. The inetaddress object depicts a 32-bit or 128-bit IP address. The Socket object represents the client's junction. ServerSocket represents the service roller socket, all of which are located in the package java.net.
Inetaddress class
The inetaddress class plays an important role in the network API socket programming. Parameters pass to the flow sleeve and self-add-in socket class constructors or non-constructor methods. Inetaddress describes 32-bit or 64-bit IP addresses. To complete this feature, the iNetAddress class mainly relys on two support class INet4address and inet6address, which is inheritance relationship, inetdrress is a parent class, Inet4address and inet6address are subclasses.
Since only one constructor is only one constructor, but cannot pass parameters, it is not possible to create an inetaddress object, such as the following practices are wrong:
Inetaddress IA = new inetaddress ();
But we can create an inetaddress object or inetaddress array through the following five factory methods.
GetAllByname (String Host) method Returns a reference to an inetadDress object, each object contains a separate IP address that represents the corresponding hostname, this IP address is passed through the Host parameter, and if there is no IP address for the specified host, if there is no IP address Method will throw a unknownhostException exception object.
GetByAddress method Returns a reference to an inetaddress object, which contains an IPv4 address or IPv6 address. The IPv4 address is a 4-byte array. The IPv6 address is a 16-byte address array, if returned Nothing is neither 4 bytes, then the method will throw a unknownhostException exception object.
GetByaddress (String Host, Byte [] addr method Returns a reference to an inetaddress object, which contains an IP address specified by the Host and 4 bytes of AddR array, or Host and 16-byte ADDR array specified The IP address, if this array is neither 4 bytes nor 16-bit bytes, then this method will throw a unknownhostException exception object. . getByname (String Host) method Returns an inetaddress object that contains an IP address corresponding to the host specified by the Host parameter. For the specified host, if there is no IP address exists, then the method will throw a unknownhostException exception object.
The getLocalHost () method returns an inetaddress object, which contains the IP address of the local machine. Considering that the local host is both a client host and a server host, in order to avoid confusion, we call the client host as a customer host, put the server The program host is called a server host.
Both of the methods mentioned above refer to a reference to returning one or more inetaddress objects. In fact, each method returns a reference to one or more Inet4address / inet6address objects, and the caller does not need to know the subtypes referenced, the opposite caller The non-static method of the inetaddress object can be invoked using the returned reference, including the polymorphism of the subtype to ensure that the overload method is called.
Inetaddress and its subtype object handle the transformation of the host name to the host IPv4 or IPv6 address. To complete this conversion, you need to use a domain name system. The following code demonstrates how to get the getByname method to get an inetaddress sub-class object, This object contains an IP address corresponding to the Host parameter:
Inetaddress IA = inetaddress.getbyname ("www.javajeff.com")));
Once the reference to the inetaddress sub-object, you can call the INetAddress's various ways to get IP address information in the inetaddress subclass object, for example, you can get standard host names from domain name services by calling getcanonicalhostname (); gethostaddress ) Get the IP address, getHostName () get the host name, isloopBackAddress () determines if the IP address is a loopback address.
List1 is a demonstration code: inetaddressDemo
// InetAddressDemo.javaimport java.net *;. Class InetAddressDemo {public static void main (String [] args) throws UnknownHostException {String host = "localhost"; if (args.length == 1) host = args [0]; Inetaddress IA = inetaddress.getbyname (Host); System.out.Println ("Canonical Host Name =" Ia.GetcanonicalHostName ()); System.out.Println ("Host Address =" Ia.GethostAddRESS ()); System .out.println ("Host Name =" Ia.getHostName ()); System.out.Println ("is loopback address =" };}} When there is no command line parameter, the code output is similar The following results:
Canonical Host Name = localhosthost address = 127.0.0.1host name = localhostis loopback address = TRUE
InetaddressDemo gave you a choice for a specified host name as a command line parameter. If there is no host name being specified, use localhost (client), INetaddressDemo get a reference to the getByName (String Host) method, The standard host name, host address, host name, and IP address are the output of the LoopBack address by this reference.
Socket class When the client needs to communicate with the server program, the client program creates a socket object in the client, and the Socket class has several constructor. Two commonly used constructors are socket (Inetaddress Addr, INT port), and socket (String Host, INT port), two constructor created a streamlined text of Socket-based connection server-side stream jacket. For the first inetaddress subclass object, the IP address of the server host is obtained through the ADDR parameter. For the second function Host parameter package is assigned to the inetaddress object, if there is no IP address consistent with the Host parameter, then the unknownhostexception exception object will be thrown . Both functions get the port number of the server through the parameter port. Assume that the connection has been established, the network API will bundle the IP address and any port number of the client based on the socket-based stream socket, otherwise the two functions will throw an IOException object.
If a socket object is created, it may obtain the information transmitted from the service program by calling the GetInputStream () method of the socket, or the output stream can also be sent by calling the getoutputstream () method to call the socket. After the read and write activity is completed, the client program calls the close () method to close the flow and streamlined connections. The following code creates a service host address of 198.163.227.6, port number 13 Socket object, and then created from this new creation The input stream is read in the Socket object, and then turn off the stream and socket objects. Socket S = New Socket ("198.163.227.6", 13); InputStream IS = S.GetinputStream (); // read from the stream.isclose (); s.close ();
Next, we will demonstrate a jacket reader, this program will create a socket object, and the socket will access the service program running on the specified host port 1000. If the access success client will send a series of commands to the service program and The response of the print service program. List2 enables us to create the source code of SSCLIENT:
Listing 2: ssclient.java
// ssclient.javaimport java.io. *; Import java.net. *; Class ssclient {public static void main (string "args) {string host =" localhost "; // if user specifies a command-line Argument, That argument // represents the host name. if (args.length == 1) Host = args [0]; bufferedreader br = null; printwriter pw = null; socket s = null; try {// create a socket That Attempts To connect to the server // program on the host at port 10000. s = new Socket (host, 10000);. // Create an input stream reader that chains to the socket's // byte-oriented input stream The input stream reader // converts bytes read from the socket to characters The // conversion is based on the platform's default character // set InputStreamReader isr;.. isr = new InputStreamReader (s.getInputStream ()); // Create a buffered reader that chains to the input Stream // reader. The Buffered Reader Supplies a communication method method // forreading entire lines of text. br = new bufferedreader isr); // Create a print writer that chains to the socket's // oriented output stream byte- The print writer creates an // intermediate output stream writer that converts // characters sent to the socket to bytes The conversion // is.. Based on The Platform's Default Character Set. Pw = new printwriter (s.getoutputstream (), true); // send the date command to the server. Pw.println ("Date"); // Obtain and Print The Current Date / Time. System.Out.println (br.readline ()); // send The Pause Command to the Server. this allows seved //clients to start and verifies That the Server is spawning // Multiple threads. Pw.println (" Pause ");
// send the dow command to the server. Pw.println ("dow"); // Obtain and print the current day of week. System.out.println (br.readline ()); // send the dom record to The server. Pw.println ("DOM"); // Obtain and print the current day of month. system.out.println (br.readline ()); // send the Doy Command to the Server. Pw.println ( "DOY"); // Obtain and print the current day of year. System.out.println (br.readline ());} catch (ioException e) {system.out.println (E.TOSTRING ());} Finally {try {if (br! = null) br.close (); if (pw! = null) PW.Close (); if (s! = null) s.close ();} catch (ooException e) { }}}} Running this program will get the following results:
Tue Jan 29 18:11:51 CST 2002TESDAY2929
SSCLIT creates a socket object to contact the service program running on the host port 10000, and the IP address of the host is determined by the Host variable. SSCLIENT will get the input and output flow of the Socket, which is very easy to read and write the string with the input stream of the bufferedReader and the output stream of the PrintWriter. The SSCLIENT Server issues a variety of DATE / TIME commands and responds, each response All are printed, once the last response is printed, the FinalLe Schiter string of the Try / Catch / Finally structure will be executed, and the Finally substring will close the bufferedReader and PrintWriter before closing the socket.
Once the SSCLIENT source code is completed, you can enter Java SSClient to perform this program. If there is a suitable program running on a different host, use the hostname / IP address as the input method of the parameter, such as www.sina.com.cn It is the host running the server program, then the input method is java ssclient www.sina.com.cn.
skill
The Socket class contains many useful methods. For example, getLocaladdress () will return a reference to the inetaddress subclass object containing the client IP address; getLocalPort () will return the port number of the client; getinetaddress () will return a reference to the inetaddress subclass object containing the server IP address; getPort () Will return the port number of the service program.
Serversocket class uses a stream sleeve in SSClient, so the service program also uses a stream socket. This is to create a serversocket object, serversocket has several constructor, the simplest ServerSocket (INT Port), when you create a ServerSocket object, the port parameter passes the port number, this port is the server listening connection request Port, if an error will throw an IOEXception exception object, otherwise the ServerSocket object will be created and ready to receive the connection request. Next, the service program enters an infinite loop, and the unlimited loop begins with the accept () method of calling ServerSocket, and the accept () method will cause the call to block until the connection is created. After establishing the connection, Accept () returns a recently created Socket object, the socket object binds the client's IP address or port number.
Since there is a single service program with multiple client program communication, the service program responds to the client should not spend a lot of time, otherwise the client program will spend a lot of time before getting the service, but the service procedure and client program The session may be very long (this is similar to the phone), so the typical way to speed up the request for the client program, the typical method is that the server host runs a background thread, the backend threading processor and the client program.
In order to demonstrate that we are talking about and complete the SSCLIENT program, let's create a SSServer program, the program will create a ServerSocket object to listen to the port 1000 connection request, if the successful service program will wait for the connection, start a thread processing connection And responsive to commands from the client. Here is the code of this program:
Listing 3: SSSERVER.JAVA
// ssserver.javaimport java.io. *; Import java.net. *; Import java.util. *; Class ssserver {public static void main (string [] args) throws oews oews oewception {system.out.println ("Server Starting) ... / N "); // Create a Server Socket That Listens on Port 10000. Serversocket Server = New Serversocket (10000); While (True) {// listen for incoming connection requests from Client / / Programs, Establish a connection, and return a socket // Object this represents this connection. Socket s = server.accept (); system.out.println ("accepting connection ... / n"); // start a thread to handle the connection new ServerThread (s) .start ();.}}} class ServerThread extends Thread {private Socket s; ServerThread (Socket s) {this.s = s;} public void run () {BufferedReader br = null PrintWriter PW = null; try {// create an input stream reader That chains to the socket's // byte-oriented input stream. The Input Stream Reader // Converts Bytes Reader // Converts Bytes Reader // Converts . From the socket to characters The // conversion is based on the platform's default character // set InputStreamReader isr;. Isr = new InputStreamReader (s.getInputStream ()); // Create a buffered reader that chains to the input stream // reader The buffered reader supplies a convenient method // for reading entire lines of text br = new BufferedReader (isr);... // Create a print writer that chains to the socket's byte- // oriented output stream The print writer creates an // Intermediate Output Stream Writer That Converts // Characters Sent To The Socket To Bytes. The Conversion // Is Based The Platform's Default Character Set. Pw =
new PrintWriter (s.getOutputStream (), true); // Create a calendar that makes it possible to obtain date // and time information Calendar c = Calendar.getInstance ();. // Because the client program may send multiple commands, a // loop is required. Keep looping until the client either // explicitly requests termination by sending a command // beginning with letters BYE or implicitly requests // termination by closing its output stream. do {// Obtain the client program's next command String cmd = br.readline (); // Exit if client program. If (cmd == null) BREAK; // Convert Command To Uppercase, for Ease of Comparison. Cmd = cmd.touppercase () ; // if Client Program Sends Bye Command, Terminate. IF (cmd.startswith ("BYE")) Break; // i c c c p r (000) Date Or Time Command, Return // Current Date / Time To The Client Program ( cmd.startswith ("Date") || cmd.startswith ("Time")) PW.Printl n (c.gettime () .tostring ()); // if Client Program Sends Dom (day of month) Command, // Return Current Day of Month To the Client Program. IF (cmd.startswith ("DOM"))) PW.Println ("" C.Get (Calendar.day_of_month)); // if Client Program Sends Dow (Day of Week) Command, // Return Current Weekday (as a string) to the client // Program. IF CMD.StartSwith ("DOW")) Switch (Cales Calendar.Sunday: PW.Println ("Sunday"); Break; Case Calendar.monday: PW.Println ("Monday") Break; Case Calendar.tuesday: PW.Println ("Tuesday"); Break;
Case Calendar.wednesday: PW.Println ("Wednesday"); Break; Case Calendar.thursday: PW.Println ("Thursday"); Break; Case Calendar.Friday: PW.Println ("Friday"); Break; Case Calendar . Saturday: PW.Println ("Saturday");} // if Client Program Sends Doy (Day of Year) Command, // Return Current Day of Year To The Client Program. IF (cmd.startswith ("DOY")) PW.Println ("" C.Get (Calendar.day_of_year); // if Client Program Sends Pause Command, Sleep for Three // Seconds. if (Cmd.StartSwith ("Pause")) Try {thread.sleep 3000);} catch (interruptedException e) {}} while; {catch (ioException e) {system.out.println (e.tostring ());} finally {system.out.println ("Closing Connection. ../N "); try {if (br! = null) br.close (); if (pw! = null) PW.Close (); if (s! = null) s.close ();} catch (IOEXCEPTION E) {}}}} Running this program will get the following output:
Server Starting ... Accepting Connection ... Closing Connection ...
SSSERVER's source code declares a pair of classes: SSServer and ServerThread; SSServer's main () method creates a ServerSocket object to listen to the connection request on port 1000, if successful, SSServer enters an infinite loop, alternately calling Serversocket's Accept ( The method is waiting to wait for the connection request while starting the request for the background thread process (Accept () returned). The thread starts from the START () method inherited by ServerThread, and executes the code in the RUN () method of ServerThread.
Once the run () method is running, the thread will create bufferedReader, PrintWriter, and Calendar objects and enter a loop, this loop is started by reading (by bufferedreader's readline ()) from the client, the text (command) is stored in the CMD reference In the String object, what happens if the customer program is too early to turn off the output flow? The answer is: CMD will not be assigned.
Note that this must be taken into account: When the service program is in the input stream, the client is turned off the output stream, and if this situation is not handled, the program will produce an exception. Once the SSServer source code is compiled, run the program by entering Java SSServer, and after starting SSSERVER, you can run one or more SSCLIENT programs.